4

iam developing a class that derives from another , but i am getting stuck , with this code:

template <class A, class B, class C>
class BaseClass
{
public:
    BaseClass(){}
    virtual void amethod( A* aPtr=0)
    {
        mAPtr=aPtr;
    }
    virtual void init()=0;
protected:
    A * mAPtr;
    B* mBPtr;
    C * mCPtr;
};
template <class A,class B,class C>
class ChildClass: public BaseClass<A,B,C>
{
public:
    ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0):mAPtr(aAptr)
      ,mBPtr(aBPtr)
      ,mCPtr(aCPtr)
    {}

};
int main()
{

    return 0;
}

The compiler out says that the child class doesnt have any of the parent field.

Compiler out:

 In constructor 'ChildClass<A, B, C>::ChildClass(A*, B*, C*)'
 In constructor 'ChildClass<A, B, C>::ChildClass(A*, B*, C*)'
error: class 'ChildClass<A, B, C>' does not have any field named 'mAPtr'
error: class 'ChildClass<A, B, C>' does not have any field named 'mBPtr'
error: class 'ChildClass<A, B, C>' does not have any field named 'mCPtr'

i have searching in google but i cannot find an answer: Thx in advance

Magnus Hoff
  • 21,529
  • 9
  • 63
  • 82
Ricardo_arg
  • 520
  • 11
  • 28

4 Answers4

6

You cannot constructor-initialize the base member variables directly in the derived class constructor.

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
    : mAPtr(aAptr)  // <-- Member belongs to parent
    , mBPtr(aBPtr) // <-- Member belongs to parent
    , mCPtr(aCPtr) // <-- Member belongs to parent
{
}

You can either default construct them in the base constructor and them assign them (since they are protected)

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
{
    mAPtr = aAptr;  // <-- Member belongs to parent but you can access it
    mBPtr = aBPtr; // <-- Member belongs to parent but you can access it
    mCPtr = aCPtr; // <-- Member belongs to parent but you can access it
}

Or you can modify the parent class constructor

BaseClass( A* aAptr, B * aBPtr0, C* aCPtr)
    : mAPtr(aAptr)
    , mBPtr(aBPtr)
    , mCPtr(aCPtr)
{
}

and

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
  : BaseClass(aAptr, aBPtr, aCPtr)
{
}

Also, remember that you need to define a void init() method in your derived class

Jason
  • 409
  • 2
  • 7
5

You cannot initialize base class' data members in a derived class' constructor's initializer list. You could assign them in the body of the constructor:

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0) {
  mAPtr = aAptr;
  mBPtr = aBPtr;
  mCPtr = aCPtr;
}

However, the base class looks badly designed: its only constructor doesn't initialize the three data members at all (not even to NULL), so they end up containing random garbage. It would probably make sense to have a three-parameter constructor in BaseClass that would initialize the data members; the constructor of ChildClass would simply forward to that, via its initialzier list.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
3

Juan, this code:

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
{
    mAPtr = aAptr;  // <-- Member belongs to parent but you can access it
    mBPtr = aBPtr; // <-- Member belongs to parent but you can access it
    mCPtr = aCPtr; // <-- Member belongs to parent but you can access it
}

will give to you the same compiler error, you need to explicitly write the base class, in the following way:

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
{
    BaseClass<A,B,C>::mAPtr = aAptr;
    BaseClass<A,B,C>::mBPtr = aBPtr;
    BaseClass<A,B,C>::mCPtr = aCPtr;
}
hidrargyro
  • 257
  • 1
  • 7
2

using the anwser from above , i have changed a little bit :

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
    {
        this->mAPtr=aAptr;
        this->mBPtr=aBPtr;
        this->mCPtr=aCPtr;
    }

without the this pointer the compiler doesnt see the variable from parent. Thx!, by the way the compilation was for Linux usign Gcc compiler gcc version 4.7.3.

Ricardo_arg
  • 520
  • 11
  • 28