【问题标题】:A riddle with classes, inheritance and polymorphism关于类、继承和多态的谜语
【发布时间】:2016-01-21 18:29:07
【问题描述】:
class A{
public:
     virtual void print() const { cout << "a" << endl; }
};

class B : public A{
    void print() const { cout << "b" << endl; }
};

void f(const A& a) {
    a.print();
}

int main() {
    A* a = new B;
    f(*a);
    return 0;
}

我应该如何改变这段代码的和平,只有func f的签名和​​A类的主体,所以它会被打印为“c”,而不需要改变这段代码中的任何其他内容。

编辑: 第一部分是这样的:

class A{
    void print() const { cout << "a" << endl; }
};

void f(const A& a) {
    a.print();
}

如何添加代码,更改f的签名和​​A的中等主体,这样字符串“b”就会被打印出来。

第二个问题,如何只改变第一个解决方案中 f 的签名,所以它会被打印出来(对于这两个问题,答案是继承、虚拟和多态。

警告 好的,确切的说法是我们可以更改 f 的签名并添加到 A 类,所以我不确定,但我认为我们不能将“a”更改为“c”。

【问题讨论】:

  • 我认为您在将家庭作业复制到帖子时弄错了一些细节。但是,即使您正确复制了作业,但在没有证据的情况下发布作业是不合适的。
  • 我认为这些功能应该被标记为虚拟的。否则,您只需将cout &lt;&lt; "a" &lt;&lt; endl; 更改为cout &lt;&lt; "c" &lt;&lt; endl;
  • 你听说过礼貌和错字吗?下面回答的人有。

标签: c++ class inheritance polymorphism virtual


【解决方案1】:

如果你只允许改变funcf签名A类的body,你必须这样做:

#include <iostream>
using namespace std;

class A{
public:
     virtual void print() const { cout << "c" << endl; }
                                        // ^ changed body "a" -> "c"
};

class B : public A{
    void print() const { cout << "b" << endl; }
};

void f( A a ) {
      // ^ changed signature: removed & and const (const can optionally be removed)
    a.print();
}

int main() {
    A* a = new B;
    f(*a);
    return 0;
}

f的参数是按值传递的,所以*a被复制到函数f的参数A a。参数的类型是A,所以a.print调用A::print

关于你的问题更改,如果你不允许将"a"更改为"c",你必须添加一个重载方法eprint而不是const

#include <iostream>
using namespace std;

class A{
public:

     virtual void print() { cout << "c" << endl; }
     //           ^^^^^  ^ add function print (without const)

     virtual void print() const { cout << "a" << endl; }
};

class B : public A{
    void print() const { cout << "b" << endl; }
};

void f( A & a ) {
    // ^ change signature -> remove const
    a.print();
}

int main() {
    A* a = new B;
    f(*a);
    return 0;
}

【讨论】:

  • 但是你在这里也改变了B级的身体。
  • 我一开始就是这么想的,但好像很琐碎,所以我在想不那么琐碎但复杂的解决方案。
  • 为什么要删除引用?无需这样做,因为无论如何都会对对象进行切片。
  • Nathan,这很可疑,因为在问题中确实提到要更改 f 的签名,否则我们只是放下虚拟并通过。而添加虚拟是问题的第一部分,所以我怀疑这不是作者要我解决的问题。
  • @Rabbid76 啊。这不是 OP 第一次发布的时候,我没有看到他们改变了它。
【解决方案2】:

这很简单。将cout替换为A::print中的输出'c',将f()的签名更改为按值接受参数。

【讨论】:

    猜你喜欢
    • 2016-04-01
    • 2015-01-02
    • 2016-11-11
    • 2016-04-14
    • 1970-01-01
    • 2020-10-31
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多