1

我想知道我应该如何为我的第四堂课调用我的构造函数。A类是基类,B类和C类继承它。

ClassA::ClassA( const string &nam, const string &ide, double bal)
        :name(nam), id(ide), balance(bal)
{
}

ClassB::ClassB(const string &nam, const string &ide, double bal)
        :ClassA(nam, ide, bal)
{
}
 ClassC::ClassC(const string &nam, const string &ide, double bal)
                :ClassA(nam, ide, bal)
{
}

现在我的第四类继承了 B 类和 C 类我应该如何为我的 D 类调用构造函数?

我尝试过这种方式,但我得到“没有匹配函数调用 ClassB::ClassB()â”

ClassD::ClassD(const string &nam, const string& ide, double bal)
        :ClassA(nam, ide, bal), ClassB(), ClassC()
{
}
4

2 回答 2

4

这里看不到的是您使用的是普通继承还是虚拟继承。这对你调用构造函数有很大的影响:

  1. 如果您使用普通继承,则每个. 一个作为实例的一部分,另一个作为实例的一部分。因此,每个中间类都使用自己的构造函数调用构造自己的基实例。ClassAClassDClassBClassC

    但是,这很可能不是您想要实现的。除了作为打结大脑的最可靠方法之一之外,您还会遇到许多问题,其中最少的是几乎任何ClassA从实例访问成员的尝试ClassD都会由于歧义而产生错误。编译器根本不知道从两个实例中的哪个实例中查找成员。

  2. 如果您使用虚拟继承,您的对象中只有一个实例ClassA。因此,无论是构造函数ClassB还是构造函数都ClassC不会构造共享基,ClassA如果这样做的话,它们将被构造两次。相反,ClassA它是在调用其他两个基本构造函数之前直接从构造函数构造的ClassD,因此您需要将调用添加到默认构造函数不会执行ClassA()的初始值设定项列表中。ClassD


回应您的评论:
您可以添加一个默认构造函数,您可以从andClassA的构造函数调用该构造函数。然后可以调用完整的构造函数,并且您不必通过and的构造函数转发参数。只要您只构造 的对象,就永远不会调用 的默认构造函数,即使它必须存在于 和 的默认构造函数的定义中。ClassBClassCClassDClassAClassBClassCClassDClassAClassBClassC

考虑以下代码:

#include <iostream>

class A {
    public:
        A() { std::cout << "A::A()\n"; }    //Not used, but required.
        A(int) { std::cout << "A::A(int)\n"; }
};

class B : public virtual A {
    public:
        B() { std::cout << "B::B()\n"; }
        B(int) : A(1) { std::cout << "B::B(int)\n"; }    //Not required.
};

class C : public virtual A {
    public:
        C() { std::cout << "C::C()\n"; }
        C(int) : A(1) { std::cout << "C::C(int)\n"; }    //Not required.
};

class D : public B, public C {
    public:
        D(int) : A(1) { std::cout << "D::D(int)\n"; }
};

int main() {
    D foo(1);
}

这个程序的输出是

A::A(int)
B::B()
C::C()
D::D(int)

如您所见,A::A()即使它永远不会被调用,B并且C是默认构造的,并且不需要传递参数。A::A(int)直接从类中调用D

于 2014-04-29T09:55:35.790 回答
0

你应该声明为:

class ClassB: public virtual Class A
{
  ...
};
class ClassC: public virtual Class A
{
  ...
};
class ClassD: public ClassB, ClassC
{
...
};
于 2014-04-29T10:03:49.583 回答