使用非默认构造函数的C ++继承

时间:2014-05-15 14:53:06

标签: c++ inheritance constructor

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

现在我想派生一个基于foo的类,名为bar,它基本上会在内部持有两个foo,而外部世界则充当单个foo。我想这样做的方法是使用两个构造函数参数y和z for bar,然后在构造函数中生成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 ::没有匹配函数来调用foo :: foo()

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

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

但这也行不通。

我还没能在网上找到一个可行的解决方案,并且非常感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

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

通过派生表单foo,您说barfoo。并且foo具有_private_var,因此您必须使用有意义的值填充此var。

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

你也可以用不同的方式实例化foo *:

   _foo_ptr_1 = foo::foo(y);

应该是

   _foo_ptr_1 = new foo(y); 

甚至更好,如果可以的话,不要让foo成为指针。如下所述:https://stackoverflow.com/a/23681932/137369

答案 1 :(得分: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代替。非常值得阅读这些实用程序类的使用。

答案 2 :(得分:1)

您可能不希望barfoo继承其实施。像这样的东西可能会更好地为你服务:

struct foo {
    virtual void do_something() = 0;
};

struct single_foo: foo {
    int x;
    single_foo(int x): x(x) {}
    void do_something() { ... }
};

struct double_foo: foo {
    single_foo x, y;
    double_foo(int x, int y): x(x), y(y) {}
    void do_something() { ... }
};