【发布时间】:2015-09-11 11:43:34
【问题描述】:
以下代码
#include <iostream>
using namespace std;
class A {};
class B : public A {};
class C : public B {};
void foo(A *a) {
cout << 'A' << endl;
}
void foo(B *b) {
cout << 'B' << endl;
}
int main() {
C *c = new C[10];
foo(c);
}
编译正常并按预期打印“B”。
但是当我将main() 函数更改为
int main() {
C c[10];
foo(c);
}
我得到一个编译器错误提示
test_arr.cpp: In function 'int main()':
test_arr.cpp:23:10: error: call of overloaded 'foo(C [10])' is ambiguous
test_arr.cpp:23:10: note: candidates are:
test_arr.cpp:11:6: note: void foo(A*)
test_arr.cpp:15:6: note: void foo(B*)
为什么现在模棱两可?我认为数组始终只是一个指针,所以我看不出有什么区别。
编辑:
我刚刚意识到我发布的整个代码一开始是个坏主意:一旦您将数据成员添加到类并在 foo 函数中访问它们,您就会遇到问题,正如 here 所解释的那样,因为foo(B*) 函数无法知道它实际上是在处理可能占用更多内存空间的C 对象。所以不要这样做!
尽管如此,我仍然有兴趣了解为什么编译器会在这里抱怨歧义,因为我真的不认为 that 有问题。
【问题讨论】:
-
在 vs2008 上,我无法重现错误 - 后一个测试用例打印“B”。
-
foo(&c[0]) 有效吗?
-
Arrays are not pointers。无论如何,这个想法是从哪里来的?此外,当您将
C的数组转换为指向B(或A,就此而言)的指针时,您需要进行数组访问的指针算法将无法解决;一旦C包含一些数据成员,b[1]将不会给你一个有效的对象,因为sizeof(B) != sizeof(C)(在此之前它也是未定义的行为)。 -
在 foo(B*) 中,你可以通过 dynamic_cast 知道它是否是一个 C。 C* c = dynamic_cast
(b) in foo(B* b) 并检查 c 是否为 nullptr(或 NULL für c++0x)。如果不是nullptr,就是C。 -
@Gombat 这些类不是多态的,不能使用
dynamic_cast。
标签: c++ arrays pointers overloading