【发布时间】:2012-07-08 14:28:05
【问题描述】:
我一直在为考试学习 c++,我以为我已经理解了大多数 c++ 常见的误解,但我在过去的考试中遇到了一个让我发疯的练习,它结合了虚拟方法和继承以一种我似乎不明白的方式是代码:
#include <iostream>
class B;
class A {
public:
virtual A* set(A* a) = 0;
};
class B : public A {
public:
virtual A* set(B* b) {
std::cout << "set1 has been called" << std::endl;
b = this;
return b;
}
virtual B* set(A* a) {
std::cout << "set2 has been called" << std::endl;
a = this;
return this;
}
};
int main(int argc, char *argv[]) {
B *b = new B();
A *a = b->set(b);
a = b->set(a);
a = a->set(b);
a = a->set(a);
return 0;
}
输出是
set1 has been called
set2 has been called
set2 has been called
set2 has been called
从我收集到的第一个调用 (b->set(b) ) 调用 B 类的第一个方法并返回 b 本身,然后这个 objectref 被强制转换为 A 意味着现在对象 b 现在是类型一种?
所以我有 A *a = A *b;
现在对我来说我应该调用 set A 是有道理的,因为我脑子里有这种情况
objectoftypeA->set(objectoftypeA) 所以我不应该研究虚拟方法,因为这两个对象是基类?
无论如何,你可以看到我有很多困惑,所以如果我犯了愚蠢的错误,我会很高兴,如果有人能解释这段代码发生了什么,我试图搜索网络,但我发现只有一个小而简单的例子不要惹麻烦。
【问题讨论】:
-
如果您描述了您期望的内容,将会很有帮助。您刚刚向我们抛出了很多代码,并在一个连续的句子中描述了您不确定的内容,这有点难以理解。很难知道从哪里开始回答。
-
我希望第二次调用会再次调用 set1,但事实并非如此,所以我猜我的整个思路都是错误的
-
对此我不太确定,但这个例子确实令人困惑。 IMO 我认为
virtual B* set(A* a)别名set2将充当virtual A* set(A* a) = 0;的实现,因为B*可以隐式转换为A*。因此,一旦您收到来自set1的A*,就会调用implmentatino,即set2。编辑:请注意,set1由于其特殊参数而无法实现纯虚函数。尝试注释掉每个函数。我猜如果set2不存在,`B *b = new B();` 会导致错误,但如果set1不存在则不会。 -
请不要自己写这样的代码:)
-
@jrok 这在现实生活中很容易发生,尽管在混合重载和覆盖时应该始终小心。 C++11提供了伪关键字
final和override来防止不小心写出这种东西。
标签: c++ inheritance pointers virtual-functions