[英]Vector of pointers to base class containing base and derived class objects - accessing derived-class specific variables
我一直在努力解决这个C++问题。 我已经创建了基类 object class 和派生类 object class 并且我试图将对基类和派生对象的引用存储在基类指针的向量中(避免 object 切片)。 使用指针,我可以运行虚方法,并且可以确认指针指向派生类 object,但是我无法获得派生类 class 的特定变量。 有什么办法吗?
基地 class object:
class Base
{
public:
Manager* manager;
Base(){}
Base(Manager* mManager){
manager = mManager;
}
virtual void init(){}
virtual void speak() {
std::cout << "Base class is speaking!" << std::endl;
}
};
导出 class object:
class Derived : public Base
{
public:
Manager* manager;
int DerviedVariable = 100;
Derived(){}
Derived(Manager* mManager){
manager = mManager;
}
void speak() override {
std::cout << "Derived class is speaking!" << std::endl;
}
};
这些对象(Base na Derived)是使用Manager class和名为groupedEntities 的数组创建和存储的:
constexpr std::size_t maxGroups = 32;
using Group = std::size_t;
class Manager
{
public:
std::array<std::vector<Base*>, maxGroups> groupedEntities;
void addToGroup(Base* mBase, Group mGroup)
{
groupedEntities[mGroup].emplace_back(mBase);
}
std::vector<Base*>& getGroup(Group mGroup)
{
return groupedEntities[mGroup];
}
template <typename T, typename... TArgs>
T* addEnt(TArgs&&... mArgs)
{
T* e(new T(this));
return e;
}
};
我正在创建对象并尝试像这样引用它们:
void main() {
std:size_t groupBlob = 0u;
Manager* manager = new Manager();
Derived* blob1(manager->addEnt<Derived>());
Derived* blob2(manager->addEnt<Derived>());
manager->addToGroup(blob1, groupBlob);
manager->addToGroup(blob2, groupBlob);
auto& grouped(manager->getGroup(groupBlob));
for (auto& e : grouped)
{
e->speak();
std::cout << e.DerviedVariable ;
}
}
不幸的是, e.DerviedVariable是不可访问的,而speak() function 说“Dervied class 正在说话”。 有什么方法可以用这种架构访问派生类变量吗? 谢谢
是的,有可能。 您只需要投射指针。 最简单的语法是:
((Derived*)e)->DerviedVariable
这等同于 C++ish
static_cast<Derived*>(e)->DerviedVariable
这里的“静态”一词提醒您没有运行时检查:编译器相信您e
确实指向Derived
的一个实例。 如果没有,则会发生未定义的行为。 更安全的选择是dynamic_cast
:
Derived *ee = dynamic_cast<Derived*>(e);
if (ee)
x = ee->DerviedVariable;
如果 object 不是Derived
的实例,它会返回 NULL。 (请注意,也可以转换引用,但由于没有 NULL 引用,如果无法转换,则dynamic_cast
将抛出)
然而,出于某种原因,使用此类转换通常被认为是一种不好的做法。 虚函数更可取,主要是因为使用它们不需要您甚至知道调用点的实际 object 类型。
在这种情况下,您可以使用dynamic_cast 。 表达式dynamic_cast<Derived*>(e)
其中e
是Base*
类型,如果e
实际上指向Derived
类型的 object,则计算结果为Derived*
,否则它将计算为 null 指针。
if(Derived* d = dynamic_cast<Derived*>(e)) {
std::cout << d->e.DerviedVariable;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.