Home > front end >  Accessing fields of child class via shared_ptr
Accessing fields of child class via shared_ptr

Time:11-13

Is it possible to access fields in the instance of child class via shared_ptr? For instance, the code below does not compile. However, if I just declare a variable like Bar bar(2), then I can access field b in a usual way, e.g. bar._b.

#include <memory>
#include <iostream>

using namespace std;

struct Foo {};

class Bar : public Foo {
public:
    Bar(int b) : _b(b) {};
    const int _b;
};

int main() {
    shared_ptr<Foo> bbar = make_shared<Bar>(3);
    cout << bbar->_b;
    return 0;
}

CodePudding user response:

The main issue is that you are using shared_ptr<Foo> as your data type, do you cannot access _b. There are 2 different way to solve this problem, each can be used in specific situations:

1. Use derived type rather than base type

Use auto or shared_ptr<Bar> for your data type:

shared_ptr<Bar> bbar = make_shared<Bar>(3); // or use `auto`

2. Polymorphic dynamic cast

Cast your data type before using:

#include <memory>
#include <iostream>

using namespace std;

struct Foo {
    virtual ~Foo() {}
};

class Bar : public Foo {
public:
    Bar(int b) : _b(b) {};
    const int _b;
};

int main() {
    shared_ptr<Foo> bbar = make_shared<Bar>(3);
    auto fbar = std::dynamic_pointer_cast<Bar>(bbar);
    cout << fbar->_b;
    return 0;
}

But in this case you need to make Foo a polymorphic type. That's why I added virtual ~Foo() {} to Foo.

CodePudding user response:

The issue with your code is that base class (Foo) does not inherit the data members of a derived class (Bar). If you would like to access a derived class data member through a base class, you would need to use virtual functions to do so.

#include <memory>
#include <iostream>

using namespace std;

class Foo {
public:
  virtual int val() = 0; // pure virtual function that needs to be overridden
};

class Bar : public Foo {
public:
    Bar(int b) : _b(b) {};
    const int _b;
    virtual int val() { return _b; }
};

int main() {
    shared_ptr<Foo> bbar = make_shared<Bar>(3);
    cout << bbar->val();
    return 0;
}
  • Related