如何在派生类中初始化需要构造函数参数的成员对象?

Posted

技术标签:

【中文标题】如何在派生类中初始化需要构造函数参数的成员对象?【英文标题】:How to initialize member objects that requires constructor parameters in derived classes? 【发布时间】:2016-02-26 10:41:47 【问题描述】:

我想在我的Base 类中包含一个Composed 对象,并且不同的派生类有不同的配置。但是Composed 类在构造函数中需要参数,我无法控制它的架构。

编译器报告错误,因为Composed 的参数应该在Base 类的初始化时传递。但我只希望它在派生类中初始化。这种情况我该怎么办?

class Base
  public:
    Base(); //Error
  protected:
    Composed comp;
;
class Composed
  public:
    Composed(int id):id(id);
  private:
    int id;
;
class Derived_1:public Base
  public:
    Derived():comp(1234);
;    
class Derived_2:public Base
  public:
    Derived():comp(2345);
;   

【问题讨论】:

Base 是否应该有一个构造函数?能不能做成纯虚拟的?如果它有一个Composed 成员但没有初始化它,那么有没有使用Base 对象? 很有道理!能给个代码示例吗? 什么?一个不存在的构造函数? 对不起,我忘记了关于 c++ 的一切。如果我删除Base的构造函数,派生类会报错“没有任何名为'comp'的字段” 恐怕信息太少了。 【参考方案1】:

您必须将该参数向上传递给 Base,然后将其传递给 comp:

class Composed
  public:
    Composed(int id):id(id);
  private:
    int id;
;
class Base
  public:
    Base(int id):comp(id)
  protected:
    Composed comp;
;
class Derived_1:public Base
  public:
    Derived():Base(1234);
;    
class Derived_2:public Base
  public:
    Derived():Base(2345);
; 

【讨论】:

傻我!忘记了所有的基础知识。谢谢! :)【参考方案2】:

假设您构造了一个Base 对象。它怎么知道要传递给comp 的构造函数的参数是什么? Base 类从根本上是有缺陷的,这就是你有错误的原因。它需要知道如何构造它的Composed 成员对象。

可以为Composed添加一个默认构造函数,然后在Derived_1Derived_2中修改这个对象。或者,正如其他人建议的那样,您可以让Base 的构造函数接受参数来构造comp。这听起来对我来说更可取,但这取决于您的用例。

请记住,当您构造 Derived_1Derived_2 时,Base 类是首先创建的,然后是其他成员变量。

【讨论】:

【参考方案3】:

有几个选项。最直接的方法是将构建 Comp 所需的对象传递给 Base 类的构造函数。

class Base
  public:
    Base(int id):comp(id)
protected:
    Composed comp;
;

class Derived_1:public Base
  public:
    Derived():Base(1234)
;    
class Derived_2:public Base
  public:
    Derived():Base(2345)
;   

另一种可能性是在基类中不包含 Comp。把它放在每个派生类中。您可以将纯虚函数添加到返回 Comp(或其地址)的 Base 类。

另一种选择是存储指向 Comp 的指针(可能是 unique_ptr)并在派生类中分配它。

【讨论】:

以上是关于如何在派生类中初始化需要构造函数参数的成员对象?的主要内容,如果未能解决你的问题,请参考以下文章

C++中的派生类,可以不定义对象直接调用基类的成员和调用自己的成员函数嘛???

C++基类和派生类的构造函数

派生类中的构造函数

superthis

对派生类的初始化

成员对象和封闭类