0

Posts that I have read that are related to my question and have answered part of it:

Using 'this' keyword in constructor

Difference between using keyword new in constructor and in data portion of a class

My question:

My specific question follows on from the topic here:

Using 'this' keyword in constructor

Are the answers provided in that topic regarding ambiguity the same for C++? Does it only matter that I use this if my parameter has the same name as my field?

Here is an example with the this keyword:

 Gui::Gui() { this->organismSize = 10.0; this->foodSize = 5.0; } 

Without the this keyword:

 Gui::Gui() { organismSize = 10.0; foodSize 5.0; } 
9
  • 5
    If you insist on using the same names for parameters and member variables then only the first version will work. Otherwise, it doesn't matter. Commented May 14, 2021 at 21:21
  • Now you have changed the question to make my comment invalid. I would prefer it if you didn't do that. Anyway, with your amended code, both versions have the same effect. Commented May 14, 2021 at 21:25
  • @PaulSanders The code was incorrect, if if I didnt change it then I wouldnt be asking the right question. Thanks for your answers. Commented May 14, 2021 at 21:29
  • 1
    Use this keyword to resolve some ambiguity. You should first use member inizializer list : organismSize{10.0} if you do this : organismSize{ organismSize } the first is the class member and the other one is the constructor parameter. Commented May 14, 2021 at 21:40
  • 1
    @PaulSanders or you could initialise members in the member initialiser list, where it is unambiguous Commented May 14, 2021 at 21:41

2 Answers 2

2

No need to use 'this' keyword in the constructor unless you have the same name for a class attribute and a parameter.

Gui::Gui(const double organismSize, const double foodSize ) { organismSize =organismSize; // we have an ambiguity, the compiler cannot make a difference between the parameter and the attribute foodSize = foodSize ; } Gui::Gui(const double organismSize, const double foodSize ) { this->organismSize =organismSize; // the compiler can make a difference between the parameter and the attribute //this->organismSize is the attribute while organismSize is the parameter this->foodSize = foodSize ; } 
Sign up to request clarification or add additional context in comments.

1 Comment

If you initialize members with an initializer list, as you should, you don’t need this to disambiguate.
2

The previous (accepted) answer is incorrect!

The main reason of using this to access the members of the class is when this class is a template, and the base class depends of the template parameter. Consider this code:

struct Base { Base () : m_baseMember(42) {} int m_baseMember; }; int m_baseMember; struct Derived : public Base { Derived() { m_baseMember = 0; m_derivedMember = 0; } int m_derivedMember; }; int main() { Derived d; cout << d.m_baseMember << ' ' << d.m_derivedMember << endl; return 0; } 

This code obviously outputs 0 0, as the assignment m_baseMember = 0; affects the member of the Base class.

Now a very similar code, but the base class becomes a template, and I instantiate it with int:

template<typename T> struct Base { Base () : m_baseMember(42) {} int m_baseMember; }; int m_baseMember; struct Derived : public Base<int> { Derived() { m_baseMember = 0; m_derivedMember = 0; } int m_derivedMember; }; int main() { Derived d; cout << d.m_baseMember << ' ' << d.m_derivedMember << endl; return 0; } 

Again the output is 0 0. Ok, let's move on. Both Base and Derived are templates...

template<typename T> struct Base { Base () : m_baseMember(42) {} int m_baseMember; }; int m_baseMember; template<typename T> struct Derived : public Base<int> { Derived() { m_baseMember = 0; m_derivedMember = 0; } int m_derivedMember; }; int main() { Derived<int> d; cout << d.m_baseMember << ' ' << d.m_derivedMember << endl; return 0; } 

The output is 0 0 again. Nothing could go wrong with this code! One more attempt: now the Derived inherits from Base<T> (and not from Base<int>):

template<typename T> struct Base { Base () : m_baseMember(42) {} int m_baseMember; }; int m_baseMember; template<typename T> struct Derived : public Base<T> { Derived() { m_baseMember = 0; m_derivedMember = 0; } int m_derivedMember; }; int main() { Derived<int> d; cout << d.m_baseMember << ' ' << d.m_derivedMember << endl; return 0; } 

And the output is... 42 0.

That is because in this very-very-very similar code the assignment m_baseMember = 0; is being applied to the global variable. The final snippet where we explicitly use this:

template<typename T> struct Base { Base () : m_baseMember(42) {} int m_baseMember; }; int m_baseMember; template<typename T> struct Derived : public Base<T> { Derived() { this->m_baseMember = 0; m_derivedMember = 0; } int m_derivedMember; }; int main() { Derived<int> d; cout << d.m_baseMember << ' ' << d.m_derivedMember << endl; return 0; } 

The output is 0 0 again, because this->m_baseMember = 0; obviously affects the class member.

5 Comments

I'm sorry, but this looks like a very complicated way to shoot oneself in the foot.
@VincentFourmond, the way to shoot yourself in the foot is avoiding this whenever working with template classes. That is why MUCH safer is to access the template class members using this.
Hmmm. I get your point, but this is only going to cause troubles inside complicated hierarchies of template classes, which is probably not what the OP had in mind.
@VincentFourmond, the question was: "Is there a difference between using 'this' keyword in the constructor of a class or not using it in C++". And the MAIN reason of using this keyword is to access the members of template classes. That is the idiomatic way to access them, because of possible latent errors.
As an aside, two-phase lookup is the key-term.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.