创建接口和Concrete类并在向量中使用它们会在调用方法时导致奇怪的行为

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建接口和Concrete类并在向量中使用它们会在调用方法时导致奇怪的行为相关的知识,希望对你有一定的参考价值。

我一直在尝试用C ++实现一个接口类(抽象类)和一些基于它的具体类。

它似乎工作得很好,直到我把它们放在shared_ptr<Interface>的向量中并尝试调用元素上的方法。

没有参数的方法按预期工作(即调用Concrete类方法),但对于带参数的方法,则调用Interface方法。

通过代码解释可能更容易,所以这里有一个显示它的最小例子。

#include <iostream>
#include <memory>
#include <vector>

class Interface{
  public:
    virtual ~Interface() = 0;
    virtual void foo(){
      std::cout << "Interface::foo" << std::endl;
    }
    virtual void bar(std::shared_ptr< Interface >){
      std::cout << "Interface::bar" << std::endl;
    }
};
Interface::~Interface(){}

class Concrete: public Interface{
  public:
    virtual void foo(){
      std::cout << "Concrete::foo" << std::endl;
    }
    virtual void bar(std::shared_ptr< Concrete >){
      std::cout << "Concrete::bar" << std::endl;
    }
};

int main(){
  std::shared_ptr< Concrete > a = std::make_shared< Concrete >();
  a->foo();
  a->bar(a);
  std::cout << std::endl;

  std::vector< std::shared_ptr< Interface > > vec{};  
  vec.push_back( a );
  vec[0]->foo();
  vec[0]->bar(a);

  return 0;
}

输出:

Concrete::foo
Concrete::bar

Concrete::foo
Interface::bar

我究竟做错了什么?顺便说一下,即使我使用带有常规指针的数组也会发生同样的情况

答案

虚拟空栏(std :: shared_ptr <Concrete>)

与基类不匹配。

virtual void bar(std :: shared_ptr <Interface>)

为了获得正确的多态行为,您需要修改具体行为以具有相同的签名。将其修改为std :: shared_ptr <Interface>。如果您使用的是C ++ 11,则可以使用override关键字使您的意图明确http://en.cppreference.com/w/cpp/language/override。如果您没有覆盖现有的虚方法,编译器将通知您。

以上是关于创建接口和Concrete类并在向量中使用它们会在调用方法时导致奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

cocos2d 如何创建继承与 ccsprite的类并在项目中使用

有没有办法将两个或多个不同的类链接到一个类中(然后在向量上使用)?

Flink Gelly 扩展边缘类并在 DataSet 中使用

创建类并在不带引号的情况下表示它

如何定义一个新的 Java 类并在运行时创建它的实例?

扩展Thread类并实现Runnable接口的场景[重复]