Функция Getter для производного класса в производном классе, при использовании указателя на базовый класс - PullRequest
0 голосов
/ 26 января 2020

У меня есть два абстрактных базовых класса, class_data и BaseClass, с производными классами overridden_class_data : public class_data и DerivedClass : public BaseClass:

class class_data{
public:
    int val_a = 0;
    double val_b = 0.;
};

class overridden_class_data : public class_data{
public:
    int val_c = 0.;
};    

class BaseClass{
public:
    BaseClass(){};

    virtual void print_data() = 0;
    virtual class_data *get_local_data() = 0;

    class_data local_class_data;
};

class DerivedClass : public BaseClass{
public:
    DerivedClass(){
        local_class_data.val_a = 10;
        local_class_data.val_b = 100.;
        local_class_data.val_c = 14;
    };

    void print_data() override{
        std::cout << "Hello World\n";
    }

    class_data * get_local_data() override {
        return &local_class_data;
    }

    overridden_class_data local_class_data;
};

Теперь, во внешних функциях, я хотел бы использовать указатель базового класса, в то же время передавая производный класс в функцию (чтобы я мог использовать одну и ту же функцию для нескольких производных классов). Чтобы получить доступ к переменной класса local_class_data, мне нужна функция-получатель, иначе будет доступна переменная класса базового класса. Здесь я хотел использовать тот же подход, то есть использовать указатель базового класса при возврате производного класса. К сожалению, это не работает, и строка

std::cout << class_pointer->get_local_data()->val_c << '\n';

приводит к ошибке компиляции

main.cc: In function ‘void test_func(BaseClass*)’:
main.cc:52:51: error: ‘class class_data’ has no member named ‘val_c’; did you mean ‘val_a’?
   52 |     std::cout << class_pointer->get_local_data()->val_c << '\n';

после того, как компилятор все еще предполагает, что я указываю на класс BaseClass (содержащий class_data), а не к классу DerivedClass, содержащему overridden_class_data.
Можно ли как-то решить мою проблему, сохранив при этом преимущества наличия абстрактного базового класса?

...