这是问题 - 我有两个这样的课程:
class A
{
//some fields and methods
void niceMethod();
};
class B : public A
{
void niceMethod();
};
class C : public A
{
void niceMethod();
};
和功能
void myFunc(A** arrayOfABC);
// Double *注意到我要修改参数。
我想做:
(*arrayOfABC)[i].niceMethod();
在我的函数中,当我传递Bs或Cs数组来运行时,完成不同的事情。
但后来我试着把它称为
B* bees = NULL;
myFunc(&bees);
我有“B **的参数类型与A **类型的参数不兼容”。
我知道我可以将B或C作为A传递给像f(A)这样的函数,但指针有什么问题?
答案 0 :(得分:3)
编译器是对的,它确实不兼容。考虑一下:
B* bees = new B[2];
myFunc(&bees); // Imagine that it's allowed
现在在myFunc
内执行此操作:
void myFunc(A** arrayOfABC) {
// This is OK:
arrayOfABC[0] = new C();
}
应该允许这样做,因为C
扩展了A
。但是,从myFunc
返回后,您的bees
将包含C
,这不是好事。
要解决此问题,请创建一个A*
数组,并使用指向B
的指针填充它。
P.S。不要忘记让niceMethod
虚拟,否则它不会像你期望的那样工作。
答案 1 :(得分:2)
您可以将B*
转换为A*
,但不能B**
转换为A**
。
假设A
是水果,B
是苹果,那么A*
是一个小箭头,可以指向水果(任何水果),B*
是一个小箭头这可以指向一个苹果(只有一个苹果)。你可以拿一个苹果箭,将它重新标记为水果箭,然后把它交给那些需要水果箭的人。它确实指向一种水果,因为苹果是一种水果。到目前为止这么好,没有惊喜。
现在A**
是一个小箭头,可以指向一个可以指向水果(任何水果)的小箭头,B**
是一个小箭头,可以指向一个小箭头,可以指向一个苹果(只有一个苹果)。如果你采取后者,并将其交给那些期望前者的人会怎么样?那个人可以沿箭头指向一个可以指向水果的箭头(任何水果!),拿出第二个箭头,然后将它转过来使它指向香蕉。
现在这个不幸的苹果家伙曾经有一个双苹果箭沿着第一个箭头走,然后沿着应该指向一个苹果的第二个箭头,并在那里找到一个香蕉,他看到了一个水果第一次在他悲惨的生活中。如果你问我,这是一个非常不幸的情况。如果事情从现在开始变成香蕉,我们不应该感到惊讶!