简体   繁体   English

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

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

I'm having trouble with constructors in derived classes. 我在派生类中遇到了构造函数的麻烦。 Lets say I have the simple code below here with one base class Base and two classes whom inherits from Base, Derived1 and Derived2. 可以说我在下面有一个简单的代码,其中有一个基类Base和两个从Base继承的类Derived1和Derived2。

I want Derived2 to hold a pointer to Base, which could point either to Base or Derived1. 我希望Derived2持有一个指向Base的指针,该指针可以指向Base或Derived1。 I cannot manage to write the constructor for this tho. 我无法为此写出构造函数。 If I pass in a Derived1 object I get a empty Base once inside the constructor. 如果传入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);
}

You likely want to accept a Base* in your constructor, rather than an actual Base instance: 您可能希望在构造函数中接受Base* ,而不是实际的Base实例:

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

Then you can pass the address-of the instance that you want your Derived2 instance to point to: 然后,您可以传递您希望Derived2实例指向的实例的地址:

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

Note that you should give them thought to the ownership of the Base object being pointed to in the Derived2 instances. 请注意,您应该让他们考虑在Derived2实例中指向的Base对象的所有权。 Additionally, if the Derived2 object persists after the passed Base object has been deleted, accessing m_b will result in undefined behavior. 此外,如果在删除传递的Base对象之后Derived2对象仍然存在,则访问m_b将导致未定义的行为。 If you can use C++11, consider passing and storing std::shared_ptr<Base> instead of a raw pointer. 如果可以使用C ++ 11,请考虑传递和存储std::shared_ptr<Base>而不是原始指针。

I understand that you want Derived2 to hold a pointer to another Base object. 我了解您希望Derived2持有指向另一个Base对象的指针。

First issue: your constructor uses a value argument for the base object: 第一个问题:您的构造函数对基础对象使用值参数:

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

This means that when it gets called, a temporary copy of the parameter passed for b is made, and you will store the address of this temporary object. 这意味着在调用它时,将为b传递一个参数的临时副本,然后您将存储此临时对象的地址。 Of course, once you leave the statement calling the constructor, this address gets invalid. 当然,一旦留下调用构造函数的语句,该地址将无效。 Segfault guaranteed sooner or later ! Segfault早晚保证!

Solution: pass argument by reference (rest of code unchanged): 解决方案:通过引用传递参数(其余代码不变):

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

Second issue: Your code doesn't compile, because Base doesn't have default constructor and the constructor for Derived1 and Derived2 do not provide for a valid Base in their initialisation list. 第二个问题:您的代码无法编译,因为Base没有默认的构造函数,并且Derived1Derived2的构造函数在其初始化列表中未提供有效的Base

Solution 1: Either provide an explicit base intialisation in ALL derived constructors. 解决方案1:在所有派生的构造函数中提供显式的基础初始化。 For example : 例如 :

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

Solution 2: Or consider using a default value for the parameter of Base constructor: 解决方案2:或考虑对Base构造函数的参数使用默认值:

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

There are many problems here. 这里有很多问题。 Let's ignore the design problems with Derived2 for now (naked pointers are evil). 现在让我们忽略Derived2的设计问题(裸指针是邪恶的)。

Focussing on Derived1 ... Derived1Derived1 ...

Derived1 is derived from Base, which means it is a Base. Derived1是从Base派生的,这意味着它 Base。 Base has only a 1-argument constructor (and therefore no default constructor) Base只有1个参数的构造函数(因此没有默认构造函数)

Derived1 has a 1-argument constructor also, but this argument is initialising Derived1's data ( m_c ). Derived1也有一个1参数的构造函数,但是此参数正在初始化Derived1的数据( m_c )。

Since Derived is a Base, the Base part of it must be constructed at construction time. 由于“派生” 基础,因此必须在构建时构建其基础部分。 Since you must construct Base, and base has only a 1-argument constructor, you must specifically mention this in the constructor of Derived1. 由于您必须构造Base,并且base只有一个1参数的构造函数,因此必须在Derived1的构造函数中特别提及。

Like this: 像这样:

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.

相关问题 以派生类为参数的 C++ 基类构造函数 (?) - C++ base class constructor taking derived class as argument (?) C++派生类构造函数调用基类构造函数错误 - C++ derived class constructor call base class constructor errors 在C ++中派生类构造函数之后调用基类构造函数 - Call base class constructor after the derived class constructor in C++ c++ 中派生的 class 构造函数中的动态基 class 构造函数调用 - dynamic base class constructor call in derived class constructor in c++ 派生类的副本构造函数(C ++)的初始化列表上的基类 - Base class on the initialisation list of a derived class' copy constructor (C++) C ++ - 实例化派生类并使用基类的构造函数 - C++ - Instantiating derived class and using base class's constructor 基类构造函数对派生类C ++不可见 - Base class constructor not visible to derived class C++ C++如何使用派生类构造函数销毁基类中的对象 - C++ how to destroy an object in the base class with a derived class constructor 从C++中具有多重继承的类派生的类:派生类试图调用根基类构造函数 - Class derived from a class with multiple inheritance in C++: the derived class is trying to call the root base class constructor 为C ++中的基类和派生类声明“虚拟”构造函数? - Declare 'virtual' constructor for base and derived class in c++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM