Thread: Using this pointer in constructor

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    87

    Using this pointer in constructor

    I've read before that using the this pointer in a constructor should be avoided. Generally I can understand that the object may not be entirely constructed yet, but I've never understood entirely what the potential issues are.

    This SO thread mentions:
    "'this' should not be used in a constructor anyways unless you know what you're doing and don't mind the limitations"
    (They also deal with shared pointers, which I should be doing...)

    This cboard thread doesn't really have any bad things to say about the practice.

    In some test code, I didn't as much as get a warning from the compiler:
    Code:
    // thistest.cpp
    
    class A;
    
    class B {
    public:
    
    B(A *a);
    private:
    A *a_;
    }; class A { public:
    A();
    private:
    B b_;
    }; A::A()
    : b_(this)
    { } B::B(A *a)
    : a_(a)
    { }
    g++ version 4.6.3
    g++ -Wall -c thistest.cpp

    For something more concrete, I have a Model class, which is more or less a fancy symbol table. I don't want to give all clients full access to the model, so I created another class, ModelReader. ModelReader can return a requested symbol from the Model, but can't do much else. I would like it if a Model could provide its own ModelReader.

    Code:
    #include "modelreader.h"
    
    class Model {
    public:
    
    Model();
    ModelReader *reader() const;
    //And some other stuff
    private:
    ModelReader reader_;
    }; Model::Model() {
    : reader_(this)
    { } ModelReader *Model::reader() const {
    return reader_;
    }
    Code:
    // modelreader.h
    
    class Model;
    
    class ModelReader {
    public:
    
    ModelReader(Model *model);
    // Some other functions here to make it useful
    private:
    Model *model_;
    }; ModelReader::ModelReader(Model *model)
    : model_(model)
    { }
    Are there any limitations to this approach?
    Are there better design alternatives?
    In general, what are the limitations / caveats to using the this pointer in a constructor?

    Thanks in advance

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    I see that you return a pointer in some public function (s). I would recommend not. I would recommend you to use & instead of *. Also mind that this way you give access to the user (!). Use at least a const reference on return
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    If you're returning a pointer or reference to class internals, you're giving full access to those class internals.


    On the question of using this in a constructor: it is acceptable to use it, but with care.

    The thing to watch, as with any constructor, is that the object is not fully constructed before the constructor completes. If you attempt to use it as if it points to a fully constructed object, then the results are either something you won't expect (virtual function dispatch doesn't call the function corresponding to the actual type of object being constructed) or undefined behaviour (eg accessing the value of a class member before the constructor has initialised it).

    It is perfectly safe to store the value of the this pointer (for example, in an array) as the value of this is determined before the constructor is invoked. The potential dangers are in using it before the constructor completes.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Are there any limitations to this approach?
    Are there better design alternatives?
    In general, what are the limitations / caveats to using the this pointer in a constructor?
    When it comes to your example, what you are doing is very dangerous and you should definately change your approach. You pass the this pointer of a not-yet-constructed Reader (not all members have been initialized yet) to a different class. If that class (ModelReader) attempts to call any member function of the Reader it recieves (in its constructor), the behaviour is undefined.

    And these are not the only issues with the this pointer.

    I don't know your exact goals, but what you should definately do is to remove the "ModelReader reader_;" member from Model. Why not allow users construct their own instances of ModelReader?

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by kmdv View Post
    When it comes to your example, what you are doing is very dangerous and you should definately change your approach. You pass the this pointer of a not-yet-constructed Reader (not all members have been initialized yet) to a different class. If that class (ModelReader) attempts to call any member function of the Reader it recieves (in its constructor), the behaviour is undefined.

    And these are not the only issues with the this pointer.

    I don't know your exact goals, but what you should definately do is to remove the "ModelReader reader_;" member from Model. Why not allow users construct their own instances of ModelReader?
    *Sigh*. Obviously you've never encountered this before. It is a well known problem (a sub-object having to know about its outer-object) with a well used solution (pass in the this pointer to the sub-object). Grumpy's post already covered that it would be bad if accessing the item through the this pointer in the constructor, but that should not be going to happen here.

    It's fine jason_m. There's no need to change anything as you're already using the common solution to the problem.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Quote Originally Posted by iMalc View Post
    It is a well known problem (a sub-object having to know about its outer-object) with a well used solution (pass in the this pointer to the sub-object).
    What he is doing is "sub-object knowing about its uninitialised outer-object" which is quite a specific case of simple "sub-object knowing about its outer-object". Storing pointer acquired during member initialisation is not always safe as well, e.g., an accidental upcast to an uninitialised base may happen, which results in undefined behaviour. Obviously, this is not the case in the simple example he posted.
    I do not understand his idea of having ModelReader instance being "fixed" in Model, but I am not getting into detail because there is not enough information. However, whether he wants to pass the this pointer to the reader only, or to the other subobjects as well (his "symbol table"), what I would recommend is to put such initialisation outside of the member initialisation list if possible - this at least guarantees no undefined behaviour.
    Last edited by kmdv; 12-30-2012 at 06:10 PM.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by kmdv View Post
    What he is doing is "sub-object knowing about its uninitialised outer-object" which is quite a specific case of simple "sub-object knowing about its outer-object".
    That's why, in my previous post, I had a rider about not using (i.e. dereferencing) the pointer until the constructor is complete.

    Quote Originally Posted by kmdv View Post
    Storing pointer acquired during member initialisation is not always safe as well, e.g., an accidental upcast to an uninitialised base may happen, which results in undefined behaviour.
    Not true.

    Firstly, within a constructor, "this" always has a static type of (const, depending on age of compiler) pointer to the type being initialised. Second, there are no circumstances in which converting a pointer to derived into a pointer to base yields undefined behaviour (the result is either ambiguity, in which case the code won't compile, or a successful conversion). Third, base class constructors are always invoked before derived class constructors so, if such an "accidental upcast" occurs, dereferencing that converted pointer always has a well defined result.

    The only way to introduce undefined behaviour is to deliberately subvert the type system (e.g. use an explicit conversion to bludgeon the compiler into submission when it complains about an invalid implicit conversion) and THEN to dereference the resultant pointer. Since such a conversion is quite deliberate, it would not qualify as an "accidental upcast".
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Agreed, this is a perfectly acceptable use of the this pointer.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 06-23-2012, 10:47 PM
  2. Replies: 4
    Last Post: 02-09-2012, 08:51 PM
  3. Replies: 4
    Last Post: 01-26-2012, 12:55 AM
  4. pointer conversion problems with a copy constructor
    By stanlvw in forum C++ Programming
    Replies: 8
    Last Post: 01-14-2008, 12:06 AM
  5. Copy constructor error, 'this' pointer conversion
    By bennyandthejets in forum C++ Programming
    Replies: 6
    Last Post: 01-08-2004, 05:18 PM