开发者

C++ Pass a hidden arg to a class constructor?

开发者 https://www.devze.com 2022-12-29 03:54 出处:网络
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:

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 pa开发者_JS百科rent so I can use it's Event Dispatcher...


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).


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.


Use a factory

class Parent
{ 
  Parent();

  Child* createChild()
  {
    return new Child(this,...);
  }
}


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号