4

我正在开发一个派生自另一个类的类,但我被卡住了,使用以下代码:

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;
}

编译器说子类没有任何父字段。

编译器输出:

 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'

我在谷歌搜索,但我找不到答案:提前谢谢

4

4 回答 4

6

您不能直接在派生类构造函数中对基成员变量进行构造函数初始化。

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
{
}

您可以在基本构造函数中默认构造它们并分配它们(因为它们受到保护)

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
}

或者可以修改父类构造函数

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

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

另外,请记住,您需要在派生类中定义一个 void init() 方法

于 2013-08-27T19:27:26.797 回答
5

您不能在派生类的构造函数的初始化列表中初始化基类的数据成员。您可以在构造函数的主体中分配它们:

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

然而,基类看起来设计得很糟糕:它唯一的构造函数根本没有初始化三个数据成员(甚至没有初始化NULL),因此它们最终包含随机垃圾。BaseClass有一个三参数构造函数来初始化数据成员可能是有意义的;的构造函数ChildClass将通过其初始化列表简单地转发给它。

于 2013-08-27T19:24:48.820 回答
3

胡安,这段代码:

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
}

会给你同样的编译器错误,你需要显式地编写基类,方式如下:

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;
}
于 2013-08-27T20:44:15.787 回答
1

使用上面的anwser,我做了一点改变:

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

没有 this 指针,编译器看不到来自父级的变量。Thx!,顺便说一下,编译是针对 Linux 使用 Gcc 编译器 gcc 版本 4.7.3。

于 2013-08-27T19:32:09.170 回答