Reputation: 4543
Suppose an object of class B is a member of class A.
class B{
//Definitions
}
class A{
public:
A();
B b_child;
int some_function();
}
One of the functions defined inside B
needs to call a (public) function from its owner (parent?) A
. Is there an immediate way to do this?
The only way I've managed to do this so far was to implement it outside the classes' definitions:
A a_obj;
a_obj.b_child.setowner(&aobj);
which tells b_child
who is its owner. I don't like this. I'd rather use some builtin method for b_child
to access its parent (if possible). If that's not possible, I'd rather pass the owner's address directly in the constructor for B
, but I don't know how to reference A
's address inside its definition.
Upvotes: 2
Views: 157
Reputation: 23135
You should define B
like the following:
template <class T, int N>
class B
{
public:
int example_func() { return static_cast<T&>(*this).some_function(); }
};
And then make B<A>
a subclass of A
(so it can call A
directly).
class A : protected B<A,0>, protected B<A,1>
{
A();
int some_function() { return 42; }
};
This is called the curiously recurring template pattern.
If you don't want B
to be a template class, and you're only going to use B
with A
, then the following is fine:
template <int N>
class B
{
public:
int example_func() { return static_cast<A&>(*this).some_function(); }
};
class A : protected B<0>, protected B<1>
{
A();
int some_function() { return 42; }
};
Alternatively, if you want to use B
with not just A
, but don't want to make B
a template class (say, if you want a collection of pointers to B
), you can do the following:
template <int N>
class B
{
public:
int example_func() { return some_function(); }
virtual int some_function() = 0;
};
class A : protected B<0>, protected B<1>
{
A();
int some_function() { return 42; }
};
This will resolve the some_function()
call at run-time, and require a virtual pointer to be stored in your class.
Upvotes: 1
Reputation: 2999
You should use this
pointer to refer to the object within itself
class B{
//Definitions
}
class A{
private:
B b_child;
public:
A()
{
b_child.set_owner(this);
}
}
Upvotes: 1
Reputation: 81349
There is no builtin method to get the 'owner' of a variable, whatever that means. Your approach of setting the owner is correct. Furthermore, doing so in the construction of B is also a correct decision. Sample code:
class B
{
public:
explicit B( A* owner ) : _owner( owner ) {}
...
private:
A* _owner;
};
class A
{
public:
A() : _child( this ) {}
...
private:
B _child;
};
Note some compilers may give you a warning for using this
in that context, but its ok for the current example. Just make sure you don't call any A
member functions from within B
constructor, since the pointer you get still points to an unconstructed object at that stage.
Upvotes: 1
Reputation: 129774
I'd rather use some builtin method for b_child to access its parent (if possible).
No, it's not.
but I don't know how to reference A's address inside its definition.
You can use this
pointer.
A() : b_child(this) { }
Upvotes: 1