-1
#include <fstream>
using namespace std;
ofstream out("order.out");

#define CLASS(ID) class ID { \
public: \
  ID(int) { out << #ID " constructor\n"; } \
  ~ID() { out << #ID " destructor\n"; } \
};

CLASS(Base1);
CLASS(Member1);
CLASS(Member2);
CLASS(Member3);
CLASS(Member4);

class Derived1 : public Base1 {
  Member1 m1;
  Member2 m2;
public:
  Derived1(int) : m2(1), m1(2), Base1(3) {
    out << "Derived1 constructor\n";
  }
  ~Derived1() {
    out << "Derived1 destructor\n";
  }
};

class Derived2 : public Derived1 {
  Member3 m3;
  Member4 m4;
public:
  Derived2() : m3(1), Derived1(2), m4(3) {
    out << "Derived2 constructor\n";
  }
  ~Derived2() {
    out << "Derived2 destructor\n";
  }
};

int main() {
  Derived2 d2;
}

“请注意,构造函数不是默认构造函数;它们每个都有一个 int 参数。参数本身没有标识符;它存在的唯一原因是强制您显式调用初始化列表中的构造函数

4

3 回答 3

1

由于这些类具有用户定义的构造函数并且该用户定义的构造函数不是默认构造函数,因此这些类中没有可用的默认构造函数。

这使得有必要在派生类的成员初始值设定项列表中显式提及可用的构造函数之一。

class Derived : public Base {
  Derived() {} // fails to compile, no constructor Base::Base() available
  Derived() : Base(3) {} // works
};

代码做了什么以及它是如何实现的。我不知道你为什么需要这样的东西,但你永远不知道。

于 2012-01-21T23:50:17.990 回答
0

提供带参数的构造函数可防止编译器合成默认构造函数。这会强制该类的用户在创建此类的实例时ID提供一个被丢弃的 。int我看不到这种方法的实际应用。

为了简化这个演示代码:

#include <iostream>

struct ID
{
    ID(int)
    {
        std::cout << "ID  constructor" << std::endl;
    }
};

int main()
{
    ID this_will_compile(0);
    ID this_will_not_compile;
}

虽然第一次创建实例ID会成功,但第二次尝试将失败。您的编译器会告诉您类似的信息:

错误:没有匹配的函数调用 'ID::ID()'</p>

从这样的类派生也是如此:

这将工作...

struct DerivedWorking: public ID
{
    DerivedWorking()
        :ID(0)
    {
    }
};

而这不会,因为它不提供inttoID的构造函数......

struct DerivedBroken: public ID
{
    DerivedBroken()
    {
    }
};
于 2012-01-22T00:24:27.063 回答
0

这意味着参数没有标识符 - 没有名称 - 因此它不会在构造函数的任何地方使用。

但是,当您创建一个属于派生类的对象时,它的构造函数会调用父类的构造函数。此外,当您有一个对象成员时,您必须在构造函数中对其进行初始化。

如果父类有一个默认(无参数)构造函数,您根本不必调用它——它会自动完成。此外,如果您不初始化对象成员,它将通过默认构造函数自动完成。

由于您的所有类实际上都没有默认构造函数,因此您必须显式调用父类构造函数,并且还必须通过具有一个参数的唯一现有构造函数初始化成员。

在所有类中使用未命名参数就是这样做的 - 强制您显式调用它们的构造函数,而不是仅仅依赖于调用的默认构造函数。

于 2012-01-21T23:53:05.620 回答