【问题标题】:run time type information (why this code don't work)运行时类型信息(为什么此代码不起作用)
【发布时间】:2013-10-28 14:53:38
【问题描述】:

我有一个类似的代码(简化以帮助提出问题)

  class a
  {
   protected:
      int m_x;
  public: 
      a(int x):m_x(x){};
      ~a(){};
      virtual int GetX()=0;
  }

  class b:public a
  {
   public: 
   b(int x):a:(x){};
    ~b(){};
      virtual int GetX(){return m_x+2;};
  }
  class c:public a
  {
   public: 
   c(int x):a:(x){};
    ~c(){};
      virtual int GetX(){return m_x+4;};
  }

我也有这些功能:

vector<a> GetData()
{
     vector<a> data;
     data.push_back(b(1));
     data.push_back(c(1));
 }

 void printData()
 { 
      vector<a> data=GetData();
      for(int I=0;i<data.size();I++)
      {
             cout<< data[I].GetX()<<endl;
      }
 }

上面的程序因为不能实例化带有虚函数的类而没有编译。

所以我把a改成了这个:

class a
  {
   protected:
      int m_x;
  public: 
      a(int x):m_x(x){};
      ~a(){};
      virtual int GetX()={return m_x};
  }

但是我没有得到正确的结果,因为我创建了 b 和 c 类型的对象,然后当我调用 GetX 时,应该调用它们的函数而不是 a。所以我得到了这些数据:

1
1

而不是

 3
 5

我该如何解决这个问题?

我应该打开编译器中的任何开关以使其工作吗?

我正在使用 Visual Studio 2012。

【问题讨论】:

  • 这个问题被称为“对象切片”。
  • 您可能想要使用类似std::vector&lt; a *&gt; 的元素,其中元素指向bc 对象...
  • 你的基类的析构函数应该是虚拟的。
  • @LokiAstari:为什么析构函数应该是虚拟的?反正它是空白的。

标签: c++ inheritance rtti


【解决方案1】:

您需要使用指针向量。幸运的是,由于您使用的是 VS2012,因此您拥有现代智能指针(以及其他一些 C++11 优点):

typedef std::vector<std::unique_ptr<a>> DataVector;

DataVector GetData() {
    DataVector data;
    data.push_back(std::unique_ptr<b>(new b(1)));
    data.push_back(std::unique_ptr<c>(new c(1)));
    return data;
}

void PrintData() { 
    for(const auto & datum : GetData())
        std::cout << datum->GetX() << std::endl;
}

【讨论】:

  • _t 结尾的标识符是为实现保留的,请不要使用它们:stackoverflow.com/a/228797/14065
  • 我更喜欢使用boost::ptr_vector。您放入指针(并且它拥有所有权),但它们在所有其他方面都被视为值,这使得它们更容易与标准算法一起使用(因为您不需要在使用前取消引用)。
  • 可能值得解释为什么(通常你应该在这样的答案中提到切片)。
  • 感谢_t 的观点,不知道那个。我喜欢在简单的问题上远离boost::,因为阅读这类问题的人常常几乎没有弄湿他们的脚,安装库有时令人生畏(尤其是对于典型的早期 Visual Studio 用户,我无论如何都找到了)并且没有必要,因为这超出了问题的范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 2011-10-25
  • 1970-01-01
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 2013-11-17
相关资源
最近更新 更多