指向继承类实例的指针作为函数参数

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**是一个小箭头,可以指向一个小箭头,可以指向一个苹果(而且只有一个苹果)。如果您将后者交给期望前者的人,会发生什么?那个人可以沿着可以指向一个可以指向一个水果(任何水果!)的箭头的箭头走,拿第二个箭头,然后把它转过来,让它指向一个香蕉。

现在那个不幸的苹果人曾经有一个双苹果箭头,沿着第一个箭头,然后沿着应该指向一个苹果的第二个箭头,在那里找到了一个香蕉,他看到了一个水果在他悲惨的一生中第一次。如果你问我,那是一个非常不幸的情况。如果事情从现在开始变得很糟糕,我们不应该感到惊讶!

【讨论】:

以上是关于指向继承类实例的指针作为函数参数的主要内容,如果未能解决你的问题,请参考以下文章

指向类方法的函数指针作为参数

用指向实例中方法的指针替换参数中的静态函数指针

C++基础之类和对象二

如何将子类作为期望基类的函数的参数传递,然后将该对象传递给指向这些抽象类对象的指针向量?

Python回调函数用法实例

指向具有多个参数作为函数参数的函数的指针