Terkadang, ada ambiguitas nama, yang dapat digunakan untuk membedakan anggota kelas dan variabel lokal. Namun, ini adalah kasus yang sama sekali berbeda this->yang secara eksplisit diperlukan.
Perhatikan kode berikut:
template<class T>struct A {int i;};template<class T>struct B : A<T>{int foo(){returnthis->i;}};int main(){
B<int> b;
b.foo();}
Jika Anda mengabaikannya this->, kompilator tidak akan tahu bagaimana memperlakukannya i, karena mungkin ada atau mungkin tidak ada di semua contoh A. Untuk memberitahunya bahwa imemang anggota dari A<T>, untuk apapun T, this->prefiks diperlukan.
Catatan: Anda masih bisa menghilangkan this->prefiks dengan menggunakan:
template<class T>struct B : A<T>{using A<T>::i;// explicitly refer to a variable in the base classint foo(){return i;// i is now known to exist}};
Ini adalah kasus yang sangat buruk. Saya pernah digigit olehnya sebelumnya.
Jason Baker
5
Ini mungkin pertanyaan konyol, tapi saya tidak mengerti mengapa itidak ada di A. Bisakah saya mendapatkan contoh?
Cam Jackson
1
@ CamJackson Saya mencoba kode di studio visual. hasilnya sama tidak peduli "ini->" ada atau tidak. Ada ide?
Peng Zhang
8
@ CamJackson: Seseorang dapat mengkhususkan kelas pada tipe:template<> struct A<float> { float x; };
Macke
31
Jika Anda mendeklarasikan variabel lokal dalam metode dengan nama yang sama sebagai anggota yang sudah ada, Anda harus menggunakan this-> var untuk mengakses anggota kelas alih-alih variabel lokal.
#include<iostream>usingnamespace std;class A
{public:int a;void f(){
a =4;int a =5;
cout << a << endl;
cout <<this->a << endl;}};int main(){
A a;
a.f();}
Ada beberapa kasus di mana penggunaan thisharus digunakan, dan ada kasus lain di mana menggunakan thispenunjuk adalah salah satu cara untuk menyelesaikan masalah.
2) Tidak Ada Alternatif: Untuk mengembalikan pointer atau referensi ke thisdari fungsi anggota. Hal ini sering dilakukan (dan harus dilakukan) ketika overloading operator+, operator-, operator=, dll:
Melakukan ini mengizinkan idiom yang dikenal sebagai " method chaining ", di mana Anda melakukan beberapa operasi pada suatu objek dalam satu baris kode. Seperti:
Beberapa menganggap ini konseptual, yang lain menganggapnya sebagai kekejian. Hitung saya di kelompok terakhir.
3) Tidak Ada Alternatif: Untuk menyelesaikan nama dalam tipe dependen. Ini muncul saat menggunakan template, seperti dalam contoh ini:
#include<iostream>template<typenameVal>classValHolder{private:Val mVal;public:ValHolder(constVal& val):
mVal (val){}Val&GetVal(){return mVal;}};template<typenameVal>classValProcessor:publicValHolder<Val>{public:ValProcessor(constVal& val):ValHolder<Val>(val){}ValComputeValue(){// int ret = 2 * GetVal(); // ERROR: No member 'GetVal'int ret =4*this->GetVal();// OK -- this tells compiler to examine dependant type (ValHolder)return ret;}};int main(){ValProcessor<int> proc (42);constint val = proc.ComputeValue();
std::cout << val <<"\n";}
4) Alternatif yang Tersedia: Sebagai bagian dari gaya pengkodean, untuk mendokumentasikan variabel mana yang merupakan variabel anggota dan bukan variabel lokal. Saya lebih suka skema penamaan yang berbeda di mana anggota varibales tidak pernah bisa memiliki nama yang sama dengan penduduk setempat. Saat ini saya menggunakan mNameuntuk anggota dan namependuduk setempat.
Dalam kasus terakhir Anda, perhatikan bahwa Anda dapat memanggil non constfungsi anggota pada sementara ( Type(rhs).swap(*this);legal dan benar) tapi kaleng sementara tidak mengikat parameter referensi non-const (menolak compiler swap(Type(rhs));serta this->swap(Type(rhs));)
Ben Voigt
4
Anda hanya perlu menggunakan this-> jika Anda memiliki simbol dengan nama yang sama di dua ruang nama potensial. Ambil contoh:
class A {public:void setMyVar(int);void doStuff();private:int myVar;}void A::setMyVar(int myVar){this->myVar = myVar;// <- Interesting point in the code}void A::doStuff(){int myVar =::calculateSomething();this->myVar = myVar;// <- Interesting point in the code}
Pada poin-poin menarik dalam kode, mengacu pada myVar akan mengacu pada myVar (parameter atau variabel) lokal. Untuk mengakses anggota kelas yang juga disebut myVar, Anda perlu menggunakan "this->" secara eksplisit.
Ini adalah salah satu penggunaan this->yang sepele untuk dihindari (berikan nama variabel lokal yang berbeda). Semua kegunaan yang sangat menarik thisbahkan tidak disebutkan oleh jawaban ini.
cmaster
4
Kegunaan lain untuk ini (seperti yang saya pikirkan ketika saya membaca ringkasan dan setengah pertanyaan ....), mengabaikan disambiguasi penamaan (buruk) di jawaban lain, adalah jika Anda ingin mentransmisikan objek saat ini, mengikatnya dalam objek fungsi atau gunakan dengan pointer-to-member.
Pemain
voidFoo::bar(){
misc_nonconst_stuff();constFoo* const_this =this;
const_this->bar();// calls const versiondynamic_cast<Bar*>(this)->bar();// calls specific virtual function in case of multi-inheritance}voidFoo::bar()const{}
Tidak, Anda tidak membutuhkannya , Anda dapat menggunakannya . Anda juga dapat menggunakan nama yang berbeda untuk argumen fungsi, yang memiliki keuntungan karena tidak memiliki dua entitas dengan nama yang sama.
cmaster
3
Tujuan utama (atau saya dapat mengatakan, satu-satunya) tujuan dari thispointer adalah menunjuk ke objek yang digunakan untuk memanggil fungsi anggota.
Berdasarkan tujuan ini, kita dapat memiliki beberapa kasus yang hanya menggunakan thispenunjuk yang dapat menyelesaikan masalah.
Misalnya, kita harus mengembalikan objek pemanggilan dalam fungsi anggota dengan argumen objek kelas yang sama:
class human {...
human & human::compare(human & h){if(condition)return h;// argument objectelsereturn*this;// invoking object}};
Atau Anda bisa membuat lengthmutable, atau bahkan meletakkannya di struct bersarang. Menghilangkan keteguhan hampir tidak pernah merupakan ide yang bagus.
Richard J. Ross III
3
Tolong jangan. Jika anggota akan diubah dari constfungsi anggota, itu harus mutable. Jika tidak, Anda membuat hidup lebih rumit untuk Anda sebagai pengelola lainnya.
research.att.com/~bs/
sekarangstroustrup.com
. Tautan baru: stroustrup.com/bs_faq2.html#thisJawaban:
Biasanya, Anda tidak harus,
this->
tersirat.Terkadang, ada ambiguitas nama, yang dapat digunakan untuk membedakan anggota kelas dan variabel lokal. Namun, ini adalah kasus yang sama sekali berbeda
this->
yang secara eksplisit diperlukan.Perhatikan kode berikut:
Jika Anda mengabaikannya
this->
, kompilator tidak akan tahu bagaimana memperlakukannyai
, karena mungkin ada atau mungkin tidak ada di semua contohA
. Untuk memberitahunya bahwai
memang anggota dariA<T>
, untuk apapunT
,this->
prefiks diperlukan.Catatan: Anda masih bisa menghilangkan
this->
prefiks dengan menggunakan:sumber
i
tidak ada diA
. Bisakah saya mendapatkan contoh?template<> struct A<float> { float x; };
Jika Anda mendeklarasikan variabel lokal dalam metode dengan nama yang sama sebagai anggota yang sudah ada, Anda harus menggunakan this-> var untuk mengakses anggota kelas alih-alih variabel lokal.
cetakan:
5
4
sumber
Ada beberapa alasan mengapa Anda mungkin perlu menggunakan
this
pointer secara eksplisit.sumber
Meskipun saya biasanya tidak terlalu menyukainya, saya pernah melihat orang lain menggunakan ini-> hanya untuk mendapatkan bantuan dari Intellisense!
sumber
Beberapa standar pengkodean menggunakan pendekatan (2) karena mereka mengklaim itu membuat kode lebih mudah dibaca.
Contoh:
Asumsikan MyClass memiliki variabel anggota yang disebut 'count'
sumber
Ada beberapa kasus di mana penggunaan
this
harus digunakan, dan ada kasus lain di mana menggunakanthis
penunjuk adalah salah satu cara untuk menyelesaikan masalah.1) Alternatif Tersedia : Untuk menyelesaikan ambiguitas antara variabel lokal dan anggota kelas, seperti yang diilustrasikan oleh @ASk .
2) Tidak Ada Alternatif: Untuk mengembalikan pointer atau referensi ke
this
dari fungsi anggota. Hal ini sering dilakukan (dan harus dilakukan) ketika overloadingoperator+
,operator-
,operator=
, dll:Melakukan ini mengizinkan idiom yang dikenal sebagai " method chaining ", di mana Anda melakukan beberapa operasi pada suatu objek dalam satu baris kode. Seperti:
Beberapa menganggap ini konseptual, yang lain menganggapnya sebagai kekejian. Hitung saya di kelompok terakhir.
3) Tidak Ada Alternatif: Untuk menyelesaikan nama dalam tipe dependen. Ini muncul saat menggunakan template, seperti dalam contoh ini:
4) Alternatif yang Tersedia: Sebagai bagian dari gaya pengkodean, untuk mendokumentasikan variabel mana yang merupakan variabel anggota dan bukan variabel lokal. Saya lebih suka skema penamaan yang berbeda di mana anggota varibales tidak pernah bisa memiliki nama yang sama dengan penduduk setempat. Saat ini saya menggunakan
mName
untuk anggota danname
penduduk setempat.sumber
Satu kasus lainnya adalah saat memanggil operator. Misalnya, bukan
bisa dibilang
Yang mungkin lebih mudah dibaca. Contoh lainnya adalah copy-and-swap:
Saya tidak tahu mengapa itu tidak tertulis
swap(temp)
tetapi ini tampaknya umum.sumber
const
fungsi anggota pada sementara (Type(rhs).swap(*this);
legal dan benar) tapi kaleng sementara tidak mengikat parameter referensi non-const (menolak compilerswap(Type(rhs));
sertathis->swap(Type(rhs));
)Anda hanya perlu menggunakan this-> jika Anda memiliki simbol dengan nama yang sama di dua ruang nama potensial. Ambil contoh:
Pada poin-poin menarik dalam kode, mengacu pada myVar akan mengacu pada myVar (parameter atau variabel) lokal. Untuk mengakses anggota kelas yang juga disebut myVar, Anda perlu menggunakan "this->" secara eksplisit.
sumber
this->
yang sepele untuk dihindari (berikan nama variabel lokal yang berbeda). Semua kegunaan yang sangat menarikthis
bahkan tidak disebutkan oleh jawaban ini.Kegunaan lain untuk ini (seperti yang saya pikirkan ketika saya membaca ringkasan dan setengah pertanyaan ....), mengabaikan disambiguasi penamaan (buruk) di jawaban lain, adalah jika Anda ingin mentransmisikan objek saat ini, mengikatnya dalam objek fungsi atau gunakan dengan pointer-to-member.
Pemain
Mengikat
ptr-ke-anggota
Semoga membantu untuk menunjukkan kegunaan lain selain ini-> anggota.
sumber
Anda perlu menggunakan
this
untuk membedakan antara parameter / variabel lokal dan variabel anggota.sumber
Tujuan utama (atau saya dapat mengatakan, satu-satunya) tujuan dari
this
pointer adalah menunjuk ke objek yang digunakan untuk memanggil fungsi anggota.Berdasarkan tujuan ini, kita dapat memiliki beberapa kasus yang hanya menggunakan
this
penunjuk yang dapat menyelesaikan masalah.Misalnya, kita harus mengembalikan objek pemanggilan dalam fungsi anggota dengan argumen objek kelas yang sama:
sumber
Saya menemukan kasus menarik lainnya dari penggunaan eksplisit pointer "ini" dalam buku Effective C ++.
Misalnya, Anda memiliki fungsi seperti konstanta
Anda tidak ingin menghitung panjang String untuk setiap panggilan, karena itu Anda ingin men-cache-nya dengan melakukan sesuatu seperti
Tapi ini tidak bisa dikompilasi - Anda mengubah objek dalam fungsi const.
Trik untuk mengatasi ini membutuhkan casting ini ke non-const ini :
Kemudian, Anda dapat melakukannya di atas
sumber
length
mutable, atau bahkan meletakkannya di struct bersarang. Menghilangkan keteguhan hampir tidak pernah merupakan ide yang bagus.const
fungsi anggota, itu harusmutable
. Jika tidak, Anda membuat hidup lebih rumit untuk Anda sebagai pengelola lainnya.