[英]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.