Malabarba
Malabarba

Reputation: 4543

Call a class function from within a child class

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

Answers (4)

Clinton
Clinton

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

srikanta
srikanta

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

K-ballo
K-ballo

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

Cat Plus Plus
Cat Plus Plus

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

Related Questions