指向继承类实例的指针作为函数参数
Posted
技术标签:
【中文标题】指向继承类实例的指针作为函数参数【英文标题】:Pointer to inherited class instance as function parameter 【发布时间】:2012-05-31 15:16:27 【问题描述】:这就是问题所在——我有两个这样的类:
class A
//some fields and methods
void niceMethod();
;
class B : public A
void niceMethod();
;
class C : public A
void niceMethod();
;
和功能
void myFunc(A** arrayOfABC);
//双*是注意我要修改参数。
而我想做:
(*arrayOfABC)[i].niceMethod();
在我的函数中,当我将 Bs 或 Cs 数组传递给函数时,会完成不同的事情。
但后来我试着这样称呼它
B* bees = NULL;
myFunc(&bees);
我有“B** 的参数类型与 A** 类型的参数不兼容”。
我知道我可以将 B 或 C 作为 A 传递给 f(A) 之类的函数,但是指针有什么问题?
【问题讨论】:
您可以接受这样的事情吗?B* bees = NULL; A* ptrs [] = bees; myFunc(ptrs);
不错的解决方案,但我决定重新考虑我的 projectc 结构以避免这个问题。
【参考方案1】:
编译器是对的,确实不兼容。考虑一下:
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
的指针填充它。
附:不要忘记将niceMethod
设为虚拟,否则它不会按您期望的方式工作。
【讨论】:
【参考方案2】:您可以将B*
转换为A*
,但不能将B**
转换为A**
。
假设A
是水果,B
是苹果,那么A*
是一个可以指向水果(任何水果)的小箭头,B*
是一个可以指向苹果的小箭头(和只有一个苹果)。你可以拿一个苹果箭,把它重新贴上水果箭的标签,然后把它交给需要水果箭的人。它确实指向一种水果,因为苹果是一种水果。到目前为止一切顺利,这里没有惊喜。
现在A**
是一个小箭头,可以指向一个小箭头,可以指向一个水果(任何水果),B**
是一个小箭头,可以指向一个小箭头,可以指向一个苹果(而且只有一个苹果)。如果您将后者交给期望前者的人,会发生什么?那个人可以沿着可以指向一个可以指向一个水果(任何水果!)的箭头的箭头走,拿第二个箭头,然后把它转过来,让它指向一个香蕉。
现在那个不幸的苹果人曾经有一个双苹果箭头,沿着第一个箭头,然后沿着应该指向一个苹果的第二个箭头,在那里找到了一个香蕉,他看到了一个水果在他悲惨的一生中第一次。如果你问我,那是一个非常不幸的情况。如果事情从现在开始变得很糟糕,我们不应该感到惊讶!
【讨论】:
以上是关于指向继承类实例的指针作为函数参数的主要内容,如果未能解决你的问题,请参考以下文章