Thread: reference to *this in initialization list?

  1. #1
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838

    reference to *this in initialization list?

    having some access violations and i'm guessing it has something to do with aforementioned.

    is something like this unsafe:

    Code:
    object():
        memberThatReferencesThis(*this)
    {
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It doesn't seem like a particularly good idea to have a reference in an object that refers to the object itself - I don't really see any purpose in that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It should be safe.

    It doesn't seem like a particularly good idea to have a reference in an object that refers to the object itself - I don't really see any purpose in that.
    A member might need to know about the owner class, so it can call it back. I assume that's a constructor call, not an initialization of the reference of the same type.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    there's an excellent purpose, however there may be a better way of doing it.

    i have a container class (tasklist) for functors (task). they have a method called exec where it iterates over a vector<task*>tasks. i require every task to have a tasklist owner that deletes it when the tasklist destructor. in an unrealted note, task has a vector called "remove from" that it iterates over in it's destructor to remove pointers to itself so that the tasklists always have valid pointers in their vector<task*>tasks.

    where this problem surfaces is that each tasklist has a member task 'run' in it that calls exec for that tasklist. run is owned by this.

    and actually, at the time of my post, i was using borland's DynamicArray class. switching to std::vector fixed the problem. (or at least covered it up for the time being, but i suspect things are ok now)

    hooray stl.
    Last edited by m37h0d; 01-28-2009 at 10:49 AM.

  5. #5
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by anon View Post
    It should be safe.



    A member might need to know about the owner class, so it can call it back. I assume that's a constructor call, not an initialization of the reference of the same type.
    thanks; and yes, you have surmised correctly.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    What might not be safe is to assume is that the object that the reference refers to is fully constructed at that point. So you can initialize the reference safely, but I don't think you should use it to call back the parent in the constructor.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    i put toDestroy ahead of run in the initialization list

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by m37h0d View Post
    having some access violations and i'm guessing it has something to do with aforementioned.

    is something like this unsafe:

    Code:
    object():
        memberThatReferencesThis(*this)
    {
    }
    It's safe so long as the constructor for the member doesn't attempt to access the reference. But the compiler warnings are annoying, so what I've done in the past is have the memberThatReferencesThis hold it as a pointer instead of a reference, and do something like this:

    Code:
    object()
    {
        memberThatReferencesThis.setContainer(this);
    }
    This method avoids the warning as well as the lingering doubts that you are doing something undefined.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    What about the boost::enable_from_this template?
    I remember reading about it in my Boost book, but I've never used it. Sounds like it might be useful in this situation though.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by anon View Post
    A member might need to know about the owner class, so it can call it back. I assume that's a constructor call, not an initialization of the reference of the same type.
    When I've done this, it's to implement multiple interfaces on an underlying object. Each interface proxies to the object through the "this" pointer which was set up during construction of the object.

    In C++ you could theoretically achieve the same thing through multiple inheritance, but that introduces other issues.

    It comes up a lot in COM programming.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #11
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    brewbuck - it seems happy enough when i declare the vectors first in the initialization list. so i guess it's one of those 'it works but carries caveats' kinda things.

    i was doing it with pointers before, just the way you said, without issue. but i've been using references everywhere else where the location binding is mandatory, as it is here, so i want to keep things as syntactically consistent as possible for my own sanity.

  12. #12
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    blah toDestroy needs to be a shared_ptr to support proper copy semantics i think...

    do i need to do anything besides stick boost in my include path to start using it? i don't think this is one of the libraries it said had to be built...

  13. #13
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    The Smart Ptr library is all templates, so no need to build anything beforehand.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  14. #14
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    ok. this is my first stab at using boost - any must reads (besides "TFM") or other pointers before i go at it?

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by m37h0d View Post
    ok. this is my first stab at using boost - any must reads (besides "TFM") or other pointers before i go at it?
    I've never needed anything but the doc web pages. Before using boost you probably want to consider whether you want to create a dependency on an external library. As cpjust said, a lot (the majority?) of Boost's functionality is contained in header files, but there are a few things, like the regex library, which need to be compiled.

    Boost is very portable, but it's something to consider before using it.

    (Some detective might dig up a comment I made recently about feeling good about using Boost in any given project -- I was referring to the functionality you get from headers only)
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. How to: Use OpenGL with Jgrasp
    By Pickels in forum Game Programming
    Replies: 3
    Last Post: 08-30-2005, 10:37 AM
  3. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  4. problem with structures and linked list
    By Gkitty in forum C Programming
    Replies: 6
    Last Post: 12-12-2002, 06:40 PM
  5. 1st Class LIST ADT
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 11-09-2001, 07:29 PM