When compiling under MSVC I get warnings about using 'this' explicitly in a constructor's initializer list. I don't get warnings if I use the return from member functions though, even member functions that return 'this'. I also experience no noticeable problems in any test* but; is using 'this' there bad, and if so why?

I want to pass 'this' of a class one of its superclass's constructors, ideally.. but if there are negative implications or possible problems, I will work around it in this new project.

* including a 'test' that was a massive project compiled originally without using MSVC, where 'this' was used in initializers extensively.

what version of vc++ are you using. The code below compiles ok without warnings with vc++ 2005 express

class foo
{
public:
    foo() {this->x = 0;}
private:
    int x;
};

int main()
{
    foo f;

    return 0;
}

>>I want to pass 'this' of a class one of its superclass's constructors
why? it already knows about the base class so there is no reason to do that.

base ( super ) classes dont know about their subclasses, they don't generally have a type-safe pointer to the fully extended class..

im using vs 2003.. but, the eg. you gave doesn't show what I mean:

class foo
{
public:
    foo():myself( this ) {}
private:
    foo * myself;
};

int main()
{
    foo f;

    return 0;
}

^^ try that, if you dont mind, when i try i get a:

warning C4355: 'this' : used in base member initializer list

(( i know that's a silly example, but, there are slightly less silly reasons for wanting to do this ))

>>base ( super ) classes dont know about their subclasses, they don't generally have a type-safe pointer to the fully extended class..
I was thinking the other way around. A base class should never need to know about its children anyway. If you want the child to implement some feature then use pure virtual functions.

>>^^ try that, if you dont mind, when i try i get a
Yes I get that warning. And I think it is because the class has not been fully constructed. But this works without that warning

class foo
{
public:
    foo(){ myself = this;}
private:
    foo * myself;
};

Well, I've stuck with pure-virtual functions in my case, I had to reorganise though. The 'base class' in question ( A ) doesn't have to be extended - It's a helper class that could be constructed to 'help' any instance of another class B, not necessarily only an instance that extends it AND that other class. So, extending a subclass of both A & B such that it can 'help itself' means it needs a reference to its fully-extended B-self.. Virtuals don't work exactly right because then it can only be created to help itself and can't exist without being a B aswell. I got around it by losing the 'help others' aspect and making most of the helper things static with an extra parameter for the B instance to 'help'. The reason I can't implement all that stuff directly in B - B is a template, specialized into C and D, and there are common functions ( that should be members ) in both specializations but not in B itself... Specializing seems to force me to write everything twice unless I do something like this. The idea to have the helper ( common functions ) work on any existing B-like object and not just a C or a D seems nice, but non-essential. I could also have bound the helper to its helpee late.. but.. I didn't want to do that.

Am more worried about other places where I use the result of member functions to provide initial values to member variables ( variables of types without default constructors - i.e. they have to be initialized using that list ), sometimes up and down the inheritance tree ( i.e. i initialize objects in a base class by the result of methods in an extending class, or the other way around ) ... so, when is it safe to have any kind of implicit reference to 'this' in the constructor initializer, which 'this', and where's it safe to pass it to? Also, only MSVC complains, and it's only a warning.. G++ ( even the latest one ) doesn't give any warnings with standard warning/error level.

This article has been dead for over six months. Start a new discussion instead.