#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 论点。参数本身没有标识符; 唯一的原因 存在就是强迫你明确地调用构造函数 初始化列表“
答案 0 :(得分:1)
由于类具有用户定义的构造函数和用户定义的构造函数 构造函数不是默认构造函数,没有默认值 这些类中可用的构造函数。
这使得有必要明确提及其中一个可用的 构造函数在派生类的成员初始值设定项列表中。
class Derived : public Base {
Derived() {} // fails to compile, no constructor Base::Base() available
Derived() : Base(3) {} // works
};
代码的作用以及它如何实现它。我不知道 为什么你应该需要这样的东西,但你永远不会知道。
答案 1 :(得分:0)
这意味着参数没有标识符 - 没有名称 - 因此它不会在构造函数的任何地方使用。
但是,当你创建一个属于派生类的对象时,它的构造函数会调用父类的构造函数。此外,当你有一个对象成员时,你必须在构造函数中初始化它。
如果父类具有默认(无参数)构造函数,则根本不需要调用它 - 它将自动完成。此外,如果您没有初始化对象成员,它将通过默认构造函数自动完成。
由于您的类中没有一个实际上具有默认构造函数,因此您必须显式调用父类构造函数,并且还通过其唯一的现有构造函数使用一个参数初始化成员。
在所有类中使用未命名的参数就是这样 - 强制您显式调用它们的构造函数,而不是仅仅依赖于被调用的默认构造函数。
答案 2 :(得分: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()'
从这样的类派生出来也是如此:
这会有用......
struct DerivedWorking: public ID
{
DerivedWorking()
:ID(0)
{
}
};
然而这不会,因为它没有提供int
到ID
的构造函数......
struct DerivedBroken: public ID
{
DerivedBroken()
{
}
};