【问题标题】:Access subclass data member from superclass array initialized using subclass objects从使用子类对象初始化的超类数组访问子类数据成员
【发布时间】:2021-06-28 03:28:19
【问题描述】:

一个最小的可重现示例:

#include<iostream>

class Super
{
    private:
    int data1;
    
    public:
    virtual int getData1(){return data1;}
};

class Sub1:public Super
{
    private:
    static const int data1 = 1;
} sub1;

class Sub2:public Super
{
    private:
    static const int data1 = 3;
} sub2;

int main()
{
    Super obj[]={sub1, sub2};
    std::cout<<obj[0].getData1()<<'\n';
    std::cout<<obj[1].getData1()<<'\n';
    return 0;
}

我需要什么:
1
3

我得到了什么:
0
0

我怎样才能做到这一点?

我在搜索过程中发现了以下内容 -
Are static variables in a base class shared by all derived classes?
Accessing subclass members from a superclass pointer C++
C++ override a member variable

Accessing subclass members from a superclass pointer C++ 看起来很相似,但它不能解决我的查询。

编辑:
我被告知这是由于object slicing

【问题讨论】:

  • 另见:What is slicing。即使你在Sub1Sub2 中覆盖getData1,如果你有一个Super 对象数组,那也对你没有任何好处。
  • @NathanPierson 注意到。有解决办法吗?

标签: c++ inheritance object-slicing


【解决方案1】:

你可以参考这个类似的问题:What is object slicing?

避免这种情况的方法是使用指针或引用,我们可以考虑使用vectorunique_ptrboost::ptr_vectorvectorreference_wrapper,但是要使用引用我们需要小心,因为我们可能会遇到悬空引用然后崩溃(引用的对象可能被破坏)。

#include <boost/ptr_container/ptr_vector.hpp>
#include <iostream>
#include <memory>

class Super {
 private:
  int data1;

 public:
  virtual int getData1() { return data1; }
};

class Sub1 : public Super {
 private:
  static const int data1 = 1;

 public:
  int getData1() { return data1; }
} sub1;

class Sub2 : public Super {
 private:
  static const int data1 = 3;

 public:
  int getData1() { return data1; }
} sub2;

void choice1() {
  std::unique_ptr<Super> obj[] = {std::make_unique<Sub1>(),
                                  std::make_unique<Sub2>()};
  std::cout << obj[0]->getData1() << '\n';
  std::cout << obj[1]->getData1() << '\n';
}
void choice2() {
  boost::ptr_vector<Super> vec;
  vec.push_back(new Sub1);
  vec.push_back(new Sub2);
  std::cout << vec[0].getData1() << '\n';
  std::cout << vec[1].getData1() << '\n';
}

【讨论】:

  • 不编译。 fatal error: boost/ptr_container/ptr_vector.hpp: No such file or directory 在没有 #include &lt;boost/ptr_container/ptr_vector.hpp&gt;choice2() 的情况下执行良好
  • 你需要安装boost库。如果你使用的是 ubuntu/debian,你可以简单地输入sudo apt install libboost-dev;对于其他 Linux 或 Windows 平台,只需 google 即可。
  • 感谢您的回答。但是,如果未覆盖函数,您的choice1() 方法将不起作用。有没有办法避免这种情况?
猜你喜欢
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
  • 2017-01-09
  • 2023-03-16
  • 2017-09-13
  • 2016-03-08
  • 2022-06-10
相关资源
最近更新 更多