0

A minimal reproducible example:

#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;
}

What I need:
1
3

What I got:
0
0

How can I achieve this?

I found the following during my search -
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++ looks similar but it doesn't solve my query.

EDIT:
I was informed that this happens due to object slicing.

Kitswas
  • 1,134
  • 1
  • 13
  • 30
  • 4
    See also: [What is slicing](https://stackoverflow.com/questions/274626/what-is-object-slicing). Even if you override `getData1` in `Sub1` and `Sub2`, that won't do you any good if you have an array of `Super` objects. – Nathan Pierson Apr 01 '21 at 06:25
  • @NathanPierson Noted. Is there a workaround? – Kitswas Apr 01 '21 at 06:37

1 Answers1

1

You may reference this similar question: What is object slicing?

The ways to avoid this is to use pointers or references, we may consider a vector of unique_ptr or boost::ptr_vector or vector of reference_wrapper, but to use reference we need to be careful since we may encounter dangling reference then get a crash(The referenced object may be destroyed).

#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';
}

prehistoricpenguin
  • 6,130
  • 3
  • 25
  • 42
  • Does not compile. `fatal error: boost/ptr_container/ptr_vector.hpp: No such file or directory` Executes well without `#include ` and `choice2()` – Kitswas Apr 01 '21 at 07:35
  • You need to install `boost` library. If your are using ubuntu/debian, you can simply type `sudo apt install libboost-dev`; For other Linux or Windows platform, just google it. – prehistoricpenguin Apr 01 '21 at 07:37
  • Thanks for the answer. However, your choice1() method doesn't work if the functions are not overridden. Is there a way to avoid that? – Kitswas Apr 01 '21 at 15:52