[英]Why is covariance not allowed with an abstract class?
class GameObject {
public:
virtual ~GameObject() {}
};
class Player: public GameObject {};
struct IGameController {
virtual GameObject* GetPlayer() = 0;
};
class CameraOnlyController : public IGameController {
public:
GameObject* GetPlayer() override { return nullptr; }
};
class PlayerController : public IGameController {
public:
PlayerController() { player = new Player(); }
~PlayerController() { delete player; }
Player* GetPlayer() override { return player; }
private:
Player* player;
};
int main() {
IGameController* playerController = new PlayerController();
Player* player = playerController->GetPlayer(); // error: a value of type "GameObject *" cannot be used to initialize an entity of type "Player *"
delete playerController;
}
如果我將控制器接口專門更改為 PlayerController,它確實會編譯
PlayerController* playerController = new PlayerController();
我知道 playerController 稍后可以像這樣指向 CameraOnlyController
playerController = new CameraOnlyController();
但是既然在 Player* 播放器初始化時它不會,為什么會被阻止? 是編譯器試圖強制執行類型安全嗎,我假設它當時知道 playerController 被分配給 new PlayerController() ,但假設這是錯誤的?
IGameController* playerController = new PlayerController();
playerController
是IGameController*
類型。
C ++編譯器的類型檢查不記得什么對playerController
。 它忘記了它是從一個指向PlayerController
的指針構造的事實。
Player* player = playerController->GetPlayer();
所以在這里它需要它被允許知道的信息,那個playerController
是一個IGameController*
,並聲明存在類型不匹配。
如果你想讓編譯器知道更多關於playerController
的類型,你必須自己改變playerController
的類型。 在確定代碼行的含義時,C++ 編譯器不會自動將playerController
的類型擴展為它所能知道的所有類型。
同時,C++ 編譯器可以自由地遵循 as-if 規則,將 playerController 的類型去playerController
。 但他們可能只會這樣做,就好像他們沒有這樣做一樣(例如,使您的代碼更快)。
存在允許對給定變量進行更廣泛類型推導的編程語言。 C++ 不是其中之一。
你可以這樣做:
auto* playerController = new PlayerController();
auto* player = playerController->GetPlayer();
delete playerController;
在這種情況下,將使用各種變量的確切類型,或
auto* playerController = new PlayerController();
Player* player = playerController->GetPlayer();
delete playerController;
這會驗證該player
是您想要的類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.