1

据我所知,您不能在 C++ 中继承构造函数。但是在某些情况下,您可能需要看起来像实例化继承类的方式与实例化它们的基类一样:

struct Base {
  int i;
  int const j;
  Base(int i, int j) : i(i), j(j) {}
};

// option 1)
struct Derived1 : Base {
  Derived1(int i, int j) : Base(i,j) {}
};
Base* baseFactory() {
  return new Derived1(42,47);
}

// option 2)
struct Derived2 : Base {
};
Base* baseFactory() {
  Base* b = new Derived2();
  b->i = 42;
  b->j = 47; // broken!
  // alternative could be to implement Base::operator=
  return b;
}

请注意,如果不是为它们的基类,则可以默认构造派生类。

我认为,选项 1 是通常所做的,但是您输入的代码没有表达任何新内容。选项 2 破坏了const正确性(并阻止您将引用用作成员),因为所有内容都必须是可分配的。

有没有一个很好的方法来解决这个问题?

编辑:C++11 很棒,但不幸的是我需要一个 C++03 解决方案。

4

4 回答 4

3

选项 1 是 C++03 中的惯用方式,它确实需要更多的输入,但语言就是这样。选项 2 甚至不接近等效项,您将无法初始化Derived2,因为Base没有默认构造函数,并且隐式声明的默认构造函数的定义Derived2需要它。

但是除了语言的技术难度之外,您正在用两阶段构造来交换构造,这绝不是一个好主意,同时迫使您使用动态分配的对象。Derived2

于 2011-10-29T12:24:21.070 回答
2

有一种替代方法:

// option 3)
struct Derived3 : Base {
  Derived3(const Base &b) : Base(b) {}
};
Base* baseFactory3() {
    return new Derived3(Base(42,47));
}

如果构建完整的 Base 对象很昂贵或需要外部资源,这可能不是一个好主意。在这种情况下,您可以创建一个轻量级对象,该对象带有 Base 的构造函数参数,这样您就有多个 BaseArguments 构造函数和一个接收 BaseArguments 的 Base 构造函数,而不是多个 Base 构造函数。但是,我认为在大多数情况下不会有很多人会考虑这种好的风格。

于 2011-10-29T13:33:48.403 回答
1

C++11 支持继承的构造函数。

http://en.wikipedia.org/wiki/C%2B%2B11

然而,并非所有现在支持 C++11 子集的编译器都支持所有功能。

Microsoft Visual C++ 2010 支持几个新的 C++0x 功能但不支持继承的构造函数,这里是一个列表:http: //blogs.msdn.com/b/vcblog/archive/2010/04/06/c-0x-core- vc10-the-table.aspx 中的语言功能

GCC 支持更多的新特性,但不支持继承的构造函数。见http://gcc.gnu.org/projects/cxx0x.html

要使 GCC 能够使用 C++0x 功能进行编译,您需要添加-std=c++0x-std=gnu++0x编译参数。Visual C++ 2010 默认启用这些。

你只需要等待:)

以前版本的标准没有干净的解决方案,因此它是在 C++11 中引入的,因为它不可能与以前的版本一起使用。因此,您唯一能做的就是复制您的构造函数并调用基本构造函数。

于 2011-10-29T10:10:25.460 回答
1

这是 Builder Pattern 的一个变体,我一直认为它可能很有用,但实际上我从来没有机会使用它;我想您可以将其称为构造函数模式。:P

它还提供了一些其他优点,例如不必按特定顺序指定参数:您只需指定您感兴趣的内容以及您想要的任何顺序。

我仍然认为只有当你的类有很多具有不同参数的构造函数时这是合理的。否则,这只是一个烦恼。

class Person
{
  public:
    class Constructor;
};

class Person::Constructor
{
  public:
    Constructor& name(const std::string&);
    Constructor& age(int);
    Person* make();
};

Person* pers = Person::Constructor()
    .name("Bob Marley").make();


class Employee : public Person
{
  public:
    class Constructor;
};

class Employee::Constructor : public Person::Constructor
{
  public:
    Constructor& salary(double);
    Employee* make();
};

Employee* emp = Employee::Constructor()
    .name("Emilly Smith").age(23).make();

但同样,只有当你的类有很多带有很多参数的构造函数并且你想避免为它们编写多个重载时,这才是合理的;否则,这只会​​增加太多的复杂性而没有任何真正的好处。

I mentioned I don't like han's proposed solution. This is because (1) you are moving the need to (re)declare a number of constructors in the child class to the need to place the same number of functions inside a factory class; (2) it is hacky and the intent is not explicit; and (3) you could view this as a violation of dependency injection.

于 2011-11-03T16:27:05.200 回答