tags:

views:

139

answers:

4

I would like to define a class that accept the pointer to it's parent class as an Argument, but would it be possible to somehow pass it without needing to pass it directly such as:

class Child
{
public:
   Child(Parent* hiddenArg);
};

class Parent
{
public:
   Child myChild;
};

I know this is weird, but I am making my own Signal/Slot implementation and Child would be a signal defined, but I would like to get the parent so I can use it's Event Dispatcher...

A: 
class Child
{
public:
   Child(Parent* hiddenArg = NULL);
};
sechastain
How can you access Parent this way?
stefaanv
This doesn't automatically pass the pointer to the parent class to its Child member, though.
AshleysBrain
+10  A: 

You can't do it automatically, but all you need to do is construct myChild in the Parent constructor like this:

Parent::Parent()
  : myChild(this)   // passing pointer to parent to child constructor
{
}

Note some compilers will emit a warning for that code: it thinks you're using the this pointer before the Parent class is fully constructed. As long as you only store the pointer in the Child constructor and don't use it, you're OK. You may legitimately want to disable the warning (try not to disable warnings project-wide though - just around the affected area).

AshleysBrain
+1 Note that the child constructor should not use the received pointer for anything other than storing it. Passing a pointer to a non fully constructed element (`Parent` in this case) and storing it is correct, but trying to dereference it is undefined behavior.
David Rodríguez - dribeas
Would myChild need to be a pointer in the parent class such as Child* myChild or this would work without needing to new it
JP
Did you try it? It should work with the code you posted, where `myChild` is an ordinary member.
AshleysBrain
Thanks a lot, trying it right now
JP
+2  A: 

If Child is a private, nested class inside parent then this is possible, but I recommend strongly against it. If Child is a public class, then there is no way to do this. How could Child possibly know what object (if any) contains it?

In any case, if the Child class is private to parent, you can derive the parent pointer from the child's this pointer. Something like the following:

class Parent {
public:
     ...

private:
    class Child {
    private:
        Parent * GetParentPointer() {
            return (Parent *)((char *)this - offsetof( Parent, m_child ));
        }
    };

    Child m_child;
 };

And just to reiterate: don't do this. No one will care if you "waste" 4 or 8 bytes on an extra pointer inside child, and the resulting code will be much more maintainable.

Peter Ruderman
Is this all defined behavior according to the standard?
AshleysBrain
Wow. It took me a minute to realize that this actually might work, but it's definitely the WRONG solution. I won't downvote it, but no +1 from me!
Mark Ransom
@AshleysBrain, I don't think `offsetof` is part of the standard.
Mark Ransom
offsetof is an ANSI C macro. In any case, I did recommend against using it twice. But I still think it's pretty cool. ;)
Peter Ruderman
Upvoting this means securing our jobs.
mxp
+1  A: 

Use a factory

class Parent
{ 
  Parent();

  Child* createChild()
  {
    return new Child(this,...);
  }
}
Harald Scheirich
Requires all `Child` classes are on the heap rather than members though.
AshleysBrain
If you are worried about creating things on the heap you should not dabble in C++. This has less caveats and is more readable than some of the other solutions suggested here (including the one that was accepted. I would need a more detailed description of the actual problem to come up with a better solution
Harald Scheirich