【问题标题】:How can I print "ABCDabcd" with these class constructors?如何使用这些类构造函数打印“ABCDabcd”?
【发布时间】:2021-08-30 14:01:33
【问题描述】:

我有以下代码:

#include <iostream>
using namespace std;
    
class A {
public:
    A() { cout << "A"; }
    A(const A&) { cout << "a"; }
};

class B : public virtual A {
public:
    B() { cout << "B"; }
    B(const B&) { cout << "b"; }
};

class C : public virtual A {
public:
    C() { cout << "C"; }
    C(const C&) { cout << "c"; }
};

class D : B, C {
public:
    D() { cout << "D"; }
    D(const D&) { cout << "d"; }
};

我想创建一个D 对象并让它打印"ABCDabcd"

我试过了:

int main()
{
    D d;
    return 0;
}

但它只打印"ABCD",我不知道如何调用其余代码。

有什么想法吗?

【问题讨论】:

  • 是的,我确定“ABCDabcd”
  • 我可以看出“ABCD”部分是为了演示构造函数。我没有看到任何应该导致“abcd”部分的东西(这就是我考虑析构函数的原因)。所以请解释一下“我想打印“ABCDabcd””对于你想要实现的实际目标意味着什么。 IE。为什么cout &lt;&lt; "ABCDabcd"; 不是答案?小写字母输出是什么意思?我怀疑它们应该通过投射来触发,但main() 或其他地方似乎没有任何东西能够触发它。
  • 我怀疑部分显示的代码是“不可编辑的”,而部分是您的作业“可编辑”的,请解释一下。
  • 查看您的代码并了解如何打印ABCD。一旦你理解了这一点,看看什么类似的事情会导致abcd 被打印出来。例如,是什么导致a 被打印?
  • 为什么cout &lt;&lt; "ABCDabcd"; 不是答案?我想你忘了解释一些规则......

标签: c++ class oop constructor virtual-functions


【解决方案1】:

您看到的输出的ABCD 部分由ABCDdefault constructors 打印。当main() 构造D 对象时,它正在调用D 的默认构造函数,它调用ABC 的默认构造函数。

输出中缺少的abcd 部分由ABCDcopy constructors 打印。所以main() 需要复制 D 对象以调用D 的复制构造函数,例如:

int main()
{
    D d;
    D d2{d}; // or: D d2 = d;
    return 0;
}

Online demo

但是,您会注意到此副本的输出将是ABCd,而不是预期的abcd。这是因为D的拷贝构造函数没有调用ABC的拷贝构造函数,而是调用了它们的默认构造函数。

要解决这个问题,您需要在每个复制构造函数中添加一个member initialization list,以便调用非默认的基本构造函数,例如:

class A {
public:
    A() { cout << "A"; }
    A(const A&) { cout << "a"; }
};

class B : public virtual A {
public:
    B() { cout << "B"; }
    B(const B &b) : A(b) { cout << "b"; }
};

class C : public virtual A {
public:
    C() { cout << "C"; }
    C(const C &c) : A(c) { cout << "c"; }
};

class D : public B, C {
public:
    D() { cout << "D"; }
    D(const D &d) : A(d), B(d), C(d) { cout << "d"; }
};

然后副本将按预期打印abcd

Online demo

【讨论】:

  • @Yunnosch 除非按照我的描述进行更改,否则复制构造函数不会产生所需的输出,否则 the output will be "ABCDABCd" instead。在这个用例中无法解决这个问题。
  • 恐怕你是对的。但是,如果目标是编写任何获得所需输出的代码,那么我将从 cout &lt;&lt; "ABCDabcd";.... 开始。有些东西不见了。但我责怪问题,而不是你的答案....
  • 感谢您的帮助,雷米! ❤️
猜你喜欢
  • 2018-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
  • 2016-12-28
相关资源
最近更新 更多