代码正在打印所有构造函数。我读到当我们从另一个类派生一个类时,构造函数不会被继承。那么为什么创建c
从b
和a
class A
{
public:
A() { cout << "A's constructor called" << endl; }
};
class B
{
public:
B() { cout << "B's constructor called" << endl; }
};
class C: public B, public A // Note the order
{
public:
C() { cout << "C's constructor called" << endl; }
};
int main()
{
C c;
return 0;
}
答案 0 :(得分:5)
当您阅读的文档说构造函数是&#34;没有继承&#34;时,如果类A
定义构造函数A::A(int x)
,那么子类{{1} }不会自动拥有一个带B
的构造函数。
但是,仍然需要初始化父类的值;否则,父对象可能处于无效状态。构造函数用于初始化类,因此意味着父类的一个&#39;必须从子构造函数的初始化列表中调用构造函数 。如果父类具有默认构造函数,则默认情况下会调用该构造函数。这就是你在你的例子中看到的。如果父级没有提供默认构造函数,则必须指定要调用的构造函数:
int
答案 1 :(得分:2)
我读到当我们从另一个类
派生一个类时,构造函数不会被继承
这是正确的。但是,你似乎误解了它的含义。
假设你有:
struct A
{
A(int) {}
};
struct B : A
{
B() : A(0) {}
};
鉴于上述情况,您将无法使用:
B b(10);
由于A(int)
未继承B
。
这是你误解的关键。
那么为什么c的创建是从b和a
调用构造函数
但是,当您构造B
时,会调用B
的构造函数来初始化其成员。还必须调用A
的构造函数,以便可以初始化与B
对应的A
的子对象。
有几种方法可以初始化A
- B
的一部分。
您可以使用以下语法在成员初始化列表中显式使用A
的构造函数:
B() : A(0) {}
将成员初始化保留为空,在这种情况下调用A
的默认构造函数。
B() {}
这相当于:
B() : A() {}
在我提供的示例中,由于提供了另一个与默认构造函数不同的构造函数,因此删除了A
的默认构造函数,因此会导致编译器错误。
回到C
的默认构造函数的实现,你有:
C() { cout << "C's constructor called" << endl; }
这相当于
C() : B(), A() { cout << "C's constructor called" << endl; }
构建B::B()
的实例时会调用 A::A()
和C
。
答案 2 :(得分:0)
构造函数不是传统意义上的继承者。
课程是继承的。
但是为了构造一个类,需要调用它的构造函数。这是它的工作。硬规则,没有例外。
当你从第二个类继承一个类时,构造第一个类也需要构造第二个类。因为第一个类总是包含第二个类。另一个硬性规则,没有例外。那是什么&#34;继承&#34;装置
因此,构造第一个类将调用其构造函数。然后,为了构造第二个类,它的构造函数也需要被调用(实际上第二个类首先被构造,然后第一个类的构造发生)。
这就是为什么两个构造函数都会被使用的原因。
答案 3 :(得分:0)
继承类时,将调用构造函数。继承基本上为派生类实例提供了基类的匿名成员实例等。需要构造这些实例,以便调用它们的构造函数。
答案 4 :(得分:0)
&#34;构造函数不是继承的&#34;意味着,C类应该并且将拥有它自己的构造函数,尽管事实上有B的构造函数,它将无法使用B的构造函数而不是C的构造函数。 这正是你得到的:你得到了所有父类的构造函数。
当你有一个类的层次结构,并从一个构造对象时,将从基础开始顺序构建所有父母。
当你将他们摧毁时,他和他所有的父母将会从他身上开始连续毁灭。
按规则:首先创建 - 最后一次破坏。
答案 5 :(得分:0)
通过不继承,C ++ 11标准意味着这个
class A
{
public:
A(int x) {}
};
class B: public A
{
};
int main(void)
{
B b(5);
return 0;
}
这将无法编译,因为A(int)
未被继承。您可以定义B
以通过
A(int)
class B: public A
{
using A::A;
};
在您的情况下,您定义所有默认ctors,以及明确定义与否,仍然存在,并且由于您的C c
声明而将作为对象初始化的一部分进行调用。
答案 6 :(得分:0)
C ++继承基本上创建了一个由其超类的部分组成的类。例如:
class A {
public:
A() {
std::cout << "Constructor A" << '\n';
}
};
class B : public A {
public:
B() {
std::cout << "Constructor B" << '\n';
}
};
class C : public B {
public:
C() {
std::cout << "Constructor C" << '\n';
}
};
C类实际上是C类,有B类部分和A类部分。因此,为了构造C类,我们需要通过调用这些部分的构造函数来构造它的每个部分。这些构造函数的顺序是从最基类到最派生类(在本例中为A到C)。 Most-base是继承树顶部的类,而派生最多的是底层的类。
同样的规则也适用于析构函数。唯一的区别是,从大多数派生到大多数派遣(C到A)都会调用派遣者。