具有非默认构造函数的 C++ 继承

Posted

技术标签:

【中文标题】具有非默认构造函数的 C++ 继承【英文标题】:C++ inheritance with non-default constructors 【发布时间】:2014-05-15 14:53:05 【问题描述】:

对于一个项目,我正在研究一个存在以下情况的案例。有一个类 foo 在构造时需要一个标识号 x。所以它的构造函数参数看起来像 foo(x)。

现在我想派生一个基于 foo 的类,称为 bar,它将基本上在内部保存两个 foo,而对外部世界则充当单个 foo。我想这样做的方法是使用 bar 的两个构造函数参数 y 和 z,然后在构造函数中生成 foo(y) 和 foo(z)。我希望它很清楚。

我当前的实现类似于:

class bar : public foo 
public:
    bar(int y, int z)
    
        _foo_ptr_1 = foo::foo(y);
        _foo_ptr_2 = foo::foo(z);
    ;

private:
    foo *_foo_ptr_1;
    foo *_foo_ptr_2;
;

其中 foo 是一个已经存在的类,类似于:

class foo 
public:
    foo(int x) :
    _private_var(x) 
    ;
;

现在,我知道由于 foo 没有带零参数的默认构造函数,这将不起作用。出于几个原因,我不希望向 foo 添加一个零参数的无意义构造函数。有什么好方法可以让这个工作吗?现在我的编译器(Ubuntu下的gcc)给了我以下错误:

error::no 调用 foo::foo() 的匹配函数

尝试解决这个问题的一个快速尝试是替换 bar 的构造函数:

bar(int y, int z) : foo(y)

但这也行不通。

我还没有在网上找到一个可行的解决方案,如果有任何帮助,我将不胜感激。

【问题讨论】:

_foo_ptr_1 = foo::foo(y) 不是在 C++ 中构造类的方式! 你确定你的 real 代码中有foo *_foo_ptr_1; 吗?此错误消息在哪里发出? 在bar的构造函数行发出错误。 既然bar 本身就是一个foo,你确定你需要额外的两个 foos 吗?也许一个额外的foo就足够了? bar 需要自己的 ID 吗?在这种情况下,它应该接受一个作为论据。如果不需要ID,为什么要继承foo 【参考方案1】:

这里的问题是您正在尝试解决继承问题。

通过派生foo 形式,您是说barfoo。一个 foo 有一个 _private_var,所以你必须用一个有意义的值填充这个 var。

如果您想以与foo 相同的方式操作,但不共享其实现,您只想与foo 共享一个接口。这是在 C++ 中通过使用仅具有纯虚函数和默认构造函数的类来完成的。例如称它为foo_interface。这应该由foo(使用“真实”实现)和bar 实现,并结合两个foo 的结果

您还应该以不同的方式实例化 foo*:

   _foo_ptr_1 = foo::foo(y);

应该是

   _foo_ptr_1 = new foo(y); 

甚至更好,如果可以的话,不要将 foo 设为指针。如此处所述:https://***.com/a/23681932/137369

【讨论】:

【参考方案2】:

这对我来说很好用:

bar(int y, int z) : foo(y)

  _foo_ptr_1 = new foo(y);
  _foo_ptr_2 = new foo(z);

请注意,尝试像静态方法一样直接调用类构造函数并不是 C++ 中构造类的方式。至少,你使用new classname(arguments),如上所述。

但实际上并不推荐这样做...使用newdelete 进行显式内存管理很容易出错。

首先,考虑到您可能根本不需要分配任何foo 实例。您可以只使用简单的成员变量:

class bar : public foo 
public:
  bar(int y, int z) : foo(y), _foo_1(y), _foo_2(z)
  
  

private:
  foo _foo_1;
  foo _foo_2;
;

如果你真的必须以困难的方式构造新实例,你应该考虑使用智能指针,例如unique_ptr

class bar : public foo 
public:
  bar(int y, int z) : foo(y), _foo_ptr_1(new foo(y)), _foo_ptr_2(new foo(z))
  
  

private:
  std::unique_ptr<foo> _foo_ptr_1;
  std::unique_ptr<foo> _foo_ptr_2;
;

unique_ptr 确保您的资源在其所有者被销毁时被正确释放。如果您的 _foo 成员变量不完全属于它们的父 bar 实例,那么您可以改用 shared_ptr。这些实用程序类的使用非常值得一读。

【讨论】:

+1 对于建议在可以避免使用指针时不要使用指针的每个人 ;) 这似乎有效,至少对于修剪过的情况,非常感谢。

以上是关于具有非默认构造函数的 C++ 继承的主要内容,如果未能解决你的问题,请参考以下文章

C++继承默认构造函数[关闭]

为啥显式允许默认构造函数和具有 2 个或更多(非默认)参数的构造函数?

类 x(继承)C++ 不存在默认构造函数

继承默认构造函数,矛盾吗?

C++提高:继承

C++提高:继承