如何从C++继承的类模板中提取数据并访问成员变量?
C++中访问继承模板类成员变量的正确方式
问题背景
我正在C++中编写一个存储类对象的vector,每个对象持有模板变量以处理不同类型的数据,使用的代码如下:
#include <iostream> #include <memory> //Declare Vector library to work with vector objects. #include <vector> #include <string> using namespace std; class AItem{ }; template <class OBJ> //Object that will hold template data. class Item : public AItem { public: //Variable to store the values. TODO: Verify if this can be made into a TEMPLATE to accept any value. OBJ value; //Constructor to store values. Item(OBJ _value): value(_value){} ~Item(){ cout << "Deleting " << value << "\n"; } }; //Main Thread. int main(){ //################################################## //################################################## // TEST SECTION //Create new Items. Item<string> *itObj = new Item<string>("TEST"); //Create a Vector that stores objects. vector <shared_ptr<AItem>> v1; //Store each item in the Array. v1.push_back(shared_ptr<AItem>(itObj)); //cout<<&v1.getValue()<<"\n"; //Iterate through each one and retrieve the value to be printed. //TODO: FIX THIS for(auto & item: v1){ cout<<item<<'\n'; } //################################################## //################################################## cout<<"Cpp Self Organizing Search Algorithm complete.\n"; return 0; }
我想要获取插入的值,但迭代时无论使用指针还是直接访问数据,只能得到内存地址,或提示类AItem不存在value属性。请问在C++中访问继承类模板中变量的正确方式是什么?
解决方案
核心问题是基类AItem既没有定义value成员,也没提供访问派生类成员的接口,而且vector存储的是shared_ptr<AItem>,编译器只能识别基类的成员,没法直接访问派生类的模板成员。下面是两种常用解决思路:
方法一:利用多态(推荐)
在基类中定义纯虚函数,让派生类实现它来返回或打印自身的value,通过基类指针就能调用派生类的具体实现:
#include <iostream> #include <memory> #include <vector> #include <string> using namespace std; class AItem{ public: // 定义纯虚函数作为访问value的统一接口 virtual void printValue() const = 0; // 基类必须加虚析构,保证派生类对象能正确销毁 virtual ~AItem() = default; }; template <class OBJ> class Item : public AItem { public: OBJ value; Item(OBJ _value): value(_value){} ~Item(){ cout << "Deleting " << value << "\n"; } // 实现基类的纯虚函数,根据模板类型打印value void printValue() const override { cout << value << "\n"; } }; int main(){ vector <shared_ptr<AItem>> v1; // 用make_shared更安全,避免手动new的内存管理问题 v1.push_back(make_shared<Item<string>>("TEST")); v1.push_back(make_shared<Item<int>>(123)); // 迭代时调用虚函数,自动匹配对应派生类的实现 for(const auto & item: v1){ item->printValue(); } cout<<"Cpp Self Organizing Search Algorithm complete.\n"; return 0; }
方法二:使用dynamic_cast类型转换
如果需要直接获取value变量,可以用dynamic_cast把基类指针转为派生类指针,转换成功后就能访问value:
int main(){ vector <shared_ptr<AItem>> v1; v1.push_back(make_shared<Item<string>>("TEST")); for(auto & item: v1){ // 尝试转换为Item<string>类型指针 auto stringItem = dynamic_cast<Item<string>*>(item.get()); if(stringItem){ cout << stringItem->value << "\n"; } // 其他类型可以类似判断 auto intItem = dynamic_cast<Item<int>*>(item.get()); if(intItem){ cout << intItem->value << "\n"; } } cout<<"Cpp Self Organizing Search Algorithm complete.\n"; return 0; }
注意:dynamic_cast会在运行时检查类型是否匹配,失败返回nullptr,所以必须判断指针有效性。这种方式需要提前知道可能的模板类型,灵活性不如多态方法,适合类型少且明确的场景。
内容的提问来源于stack exchange,提问作者rasa911216
相关产品推荐
相关产品推荐

