1

I haven't worked with derived classes and polymorphism in a while, and I can't figure out how to access a derived class data item.

// Quick example
class Base {
  string data1;  // data1 = "FOO"
};
class ChildA : public Base {
  string data2;
};


int main() {
Base **list;
list = new Base*[1];
base[0] = new ChildA(// data2 = "BAR");
std::cout << base[0]->data1; // FOO
std::cout << base[0]->data2; // Error; no member named "data2" in Base

Is it possible to retrieve the derived data from the base class array?

4
  • Read about virtual member functions (there is no polymorphism in your sample, whatsoever) Commented Nov 28, 2014 at 19:34
  • 1
    Access privilege in classes is private by default. Commented Nov 28, 2014 at 19:38
  • 1
    The point about polymorphism is to design your program so that you don't end up doing what your code is doing. The point is you don't want to care about the specifics of the type especially not what their internal data looks like. Commented Nov 28, 2014 at 19:42
  • You might read: cs.bu.edu/teaching/cpp/polymorphism/intro Commented Nov 28, 2014 at 19:43

3 Answers 3

3

When you're looking at an instance of a derived class through a pointer to the base class, you can only see the members of the base class, because generally, you wouldn't know what subtype instance you are looking at. The point of polymorphism and virtual functions is that in many cases, you can work with subtype instances without knowing their actual type. For instance, if you want to print information about an instance, and you want data2 to be included when you print a ChildA, you would create a virtual toString() function in Base and override it in ChildA to include data2. Then, you can call toString() without knowing the actual type, and if your instance is actually a ChildA, you'll get data2.

Sign up to request clarification or add additional context in comments.

2 Comments

Ahh, that's disappointing. I really thought there was some way to cast it as the type and retrieve the data, but it seems there isn't. This is why you have to practice your old languages every now and then!
@user3470131: Ah, I didn't understand that you were looking for typecasting. You can do (static_cast<ChildA*>(base[0]))->data2 if you're sure of the type, or (dynamic_cast<ChildA*>(base[0])) if you're not - the latter will produce NULL if the type you specify doesn't match the runtime type. But if you need to do this other than for playing around, you might want to reconsider your design.
0

class member variable by default is private. by using base class pointer, you can not get derived class member var at all.

If you would like to do so, you may want to implement virtual getter function, it will help you getting private member function from derived class.

Comments

0

If the base class interface must have knowledge of data potentially held in a derived class, here is one of the few ways that is not horribly dangerous.

#include <iostream>
#include <vector>
#include <utility>
#include <memory>
#include <stdexcept>

using namespace std;

class Base {
public:
    Base(std::string d1 = {"FOO"} ) : _data1 { std::move(d1) } {}
    virtual ~Base() = default; // because polymorphism without a virtual base class is naughty
    const string& data1() const { return _data1; }

    virtual bool has_data2() const { return false; }
    virtual const string& data2() const {
        throw invalid_argument {"I don't have data2"};
    };

private:
    string _data1;  // data1 = "FOO"
};

class ChildA : public Base {
public:
    ChildA(std::string d2, std::string d1 = {"FOO"})
    : Base { std::move(d1) }
    , _data2 { std::move(d2) }
    {}

    bool has_data2() const override { return true; }
    const std::string& data2() const override {
        return _data2;
    };

private:
    string _data2;
};

int main()
{
    vector<unique_ptr<Base>> bases;
    bases.push_back(unique_ptr<Base>(new ChildA("bob")));
    bases.push_back(unique_ptr<Base>(new Base("not foo")));

    for(const auto& p : bases) {
        cout << p->data1() << ", " << (p->has_data2() ? p->data2() : "no data 2") << endl;
    }

    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.