繁体   English   中英

基类作为C ++中派生类构造函数中的参数

[英]Base class as argument in derived class constructor in c++

我在派生类中遇到了构造函数的麻烦。 可以说我在下面有一个简单的代码,其中有一个基类Base和两个从Base继承的类Derived1和Derived2。

我希望Derived2持有一个指向Base的指针,该指针可以指向Base或Derived1。 我无法为此写出构造函数。 如果传入Derived1对象,则在构造函数中会得到一个空的Base。

Class Base
{
public:
      Base(int a): m_a(a)
      {
      }

protected:
         int m_a;
};


//First derived class of base
class Derived1 : public Base
{
public:
        Derived1(double c): m_c(c)
        {
        }

private:
        double m_c;
};


//Second derived class of Base
class Derived2 : public Base
{
public:
        Derived2(Base b, int k): m_b(&b), m_k(k)
        {
        }

private:
        int m_k;
        Base* m_b;
};


int main()
{
    Base b(2);
    Derived1 d1(3.0);


    Derived2 d2(d1, 3);
    Derived2 d3(b, 4);
}

您可能希望在构造函数中接受Base* ,而不是实际的Base实例:

Derived2(Base* b, int k) : m_b(b), m_k(k)
{
}

然后,您可以传递您希望Derived2实例指向的实例的地址:

Derived2 d2(&d1, 3);
Derived2 d3(&b, 4);

请注意,您应该让他们考虑在Derived2实例中指向的Base对象的所有权。 此外,如果在删除传递的Base对象之后Derived2对象仍然存在,则访问m_b将导致未定义的行为。 如果可以使用C ++ 11,请考虑传递和存储std::shared_ptr<Base>而不是原始指针。

我了解您希望Derived2持有指向另一个Base对象的指针。

第一个问题:您的构造函数对基础对象使用值参数:

    Derived2(Base b, int k): m_b(&b), m_k(k)

这意味着在调用它时,将为b传递一个参数的临时副本,然后您将存储此临时对象的地址。 当然,一旦留下调用构造函数的语句,该地址将无效。 Segfault早晚保证!

解决方案:通过引用传递参数(其余代码不变):

    Derived2(Base& b, int k): m_b(&b), m_k(k)

第二个问题:您的代码无法编译,因为Base没有默认的构造函数,并且Derived1Derived2的构造函数在其初始化列表中未提供有效的Base

解决方案1:在所有派生的构造函数中提供显式的基础初始化。 例如 :

    Derived2(Base& b, int k) : m_b(&b), m_k(k), Base(k)  // is k the right value ? 
    { ... }

解决方案2:或考虑对Base构造函数的参数使用默认值:

    Base(int a=0): m_a(a)  // default parameter is 0 
    { ... }

这里有很多问题。 现在让我们忽略Derived2的设计问题(裸指针是邪恶的)。

Derived1Derived1 ...

Derived1是从Base派生的,这意味着它 Base。 Base只有1个参数的构造函数(因此没有默认构造函数)

Derived1也有一个1参数的构造函数,但是此参数正在初始化Derived1的数据( m_c )。

由于“派生” 基础,因此必须在构建时构建其基础部分。 由于您必须构造Base,并且base只有一个1参数的构造函数,因此必须在Derived1的构造函数中特别提及。

像这样:

class Derived1 : public Base
{
public:
    Derived1(double c, int some_value_for_base)
    : Base(some_value_for_base)
    , m_c(c)
    {
    }

...
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM