Основываясь на комментариях к моему последнему вопросу ( Getter-функция для производного класса в производном классе, при использовании указателя на базовый класс ), мне сказали, что я должен использовать static_cast при перезаписи моего указатель от базового класса на производный класс, чтобы получить доступ к производному классу. Я проверил это, используя следующий код:
#include <iostream>
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 overridden_class_data_II : public class_data{
public:
int val_c = 12.;
};
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;
};
class DerivedClassII : public BaseClass{
public:
DerivedClassII(){
local_class_data.val_a = 10;
local_class_data.val_b = 100.;
};
void print_data() override{
std::cout << "Hello World\n";
}
class_data * get_local_data() override {
return &local_class_data;
}
overridden_class_data_II local_class_data;
};
void test_func(BaseClass *class_pointer){
std::cout << class_pointer->get_local_data()->val_a << '\n';
std::cout << class_pointer->local_class_data.val_a << '\n';
class_pointer->local_class_data.val_a = 5;
std::cout << class_pointer->local_class_data.val_a << '\n';
std::cout << class_pointer->get_local_data()->val_a << '\n';
class_pointer->get_local_data()->val_a = 15;
std::cout << class_pointer->local_class_data.val_a << '\n';
std::cout << class_pointer->get_local_data()->val_a << '\n';
std::cout << static_cast<overridden_class_data*>(class_pointer->get_local_data())->val_c << '\n';
}
int main(void){
std::cout << "From main\n";
DerivedClass DClass;
DerivedClassII EClass;
std::cout << "DClass: \n";
test_func(&DClass);
std::cout << "EClass: \n";
test_func(&EClass);
return 0;
}
Здесь у меня есть два производных класса, которые используют два различных производных класса в качестве переменной класса. Чтобы получить доступ к данным этих классов, я должен использовать static_cast на возвращенный указатель базового класса, чтобы привести его обратно к производному классу. Тем не менее, я не хочу переписывать функцию test_func()
для обоих классов, но вместо этого использую для них одну и ту же функцию.
Изначально я подумал, что мне пришлось дважды написать последнюю строку функции, переписав указатель переменной класса один раз на overridden_class_data*
и один раз на overridden_class_data_II*
, в зависимости от входного класса. Но после тестирования я заметил, что мне не нужно этого делать, я могу изменить его на overridden_class_data*
, но он все равно действует, как если бы я преобразовал его overridden_class_data_II*
. Почему? Это потому, что оба класса содержат одинаковые элементы, и, следовательно, указатель может указывать на одну и ту же точку?