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

问题描述 投票:1回答:1

我一直在尝试用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

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

c++ vector abstract-class
1个回答
1
投票

虚拟空栏(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。如果您没有覆盖现有的虚方法,编译器将通知您。

© www.soinside.com 2019 - 2024. All rights reserved.