簡體   English   中英

這里適合哪種類型的演員?

[英]What type of cast is appropriate here?

我有一個像這樣定義的名為BaseNode抽象類模板

template<class T>
class BaseNode
{
public:
    T* addChildNode(const char *name);
    void deleteChildNode(const char *name);
    void deleteAllChildNodes();

    T* findFirstNode(const char *name);
    T* getChildNode(const char *name);
    T* getChildNode(unsigned int index);

    void setName(const char *name);
    void setTranformation(const glm::mat4 &transformation);

    unsigned int getNumChildren() const { return _children.size(); }
    const char *name() const { return _name.c_str(); }
    T* parent() const { return _parent; }
    const glm::mat4& transformation() const { return _transformation; }
    const glm::mat4& toRootTransformation() const { return _toRoot; }

protected:
    BaseNode(const char *nodeName, T *parent);
    virtual ~BaseNode();

    std::string _name;

    glm::mat4 _transformation;
    glm::mat4 _toRoot;

    T *_parent;
    std::vector<T*> _children;
};

該類的功能是,我可以創建自己的“節點類”類型,然后它們將繼承該類模板的所有場景圖方法。 (例如, class MyNode : public BaseNode<MyNode> {...};

addChildNode(const char *name)函數插入一個new T(name, this)給孩子矢量,當this應該是孩子的父母。 編譯器拋出強制類型轉換錯誤,並建議我為此使用某種強制類型轉換。 我目前正在使用dynamic_cast ,但這確實讓我感到困擾,因為我認為它沒有用。

我的問題是,在這種情況下使用reinterpret_cast(基本上就像C-cast ..?)是否安全,例如: _children.push_back(new T(name, reinterpret_cast<T*>(this))); 因為IMO dynamic_cast將永遠不會失敗。

這是一個奇怪的重復模板模式的例子,因此static_cast在這里是慣用的。

在這種情況下,您可以通過多種方式避免進行投射。 最簡單的是將構造函數更改為:

BaseNode(const char* nodeName, T* parent, T* thisAsT);

並添加適當的字段:

//...
T* _parent;
T* _thisAsT;

因此,在addChildNode您可以輕松訪問具有適當類型的this指針:

_children.push_back(new T(name, _thisAsT));

當然,這需要您的派生類在其構造函數中為此參數提供有效的指針。


另一個,但是有點麻煩的是添加:

virtual T* buildFromName(const char* name) = 0;

然后在addChildNode使用它:

_children.push_back(buildFromName(name));

但是,這需要派生類為自己的類型實現工廠方法,例如,這違反了SRP 另一方面,為每個派生類創建工廠類型似乎是一個過大的選擇。


第二個想法,具有與上述類似的屬性:

virtual T* getThis() = 0;

接着:

_children.push_back(new T(name, getThis()));

旁注:

-考慮使用std::string而不是const char*

-聲明應寫為T* x而不是T *x (也可以用const char* x代替const char *x )-星號不是變量名稱的一部分,它是類型說明符的一部分,因此應啟用“類型方面”

static_cast是正確的。
dynamic_cast比您需要的慢得多。 reinterpret_cast錯誤。 您不知道派生對象的基類部分在與派生對象相同的位置開始。 如果需要,靜態強制轉換會調整地址。 reinterpret_cast沒有。

dynamic_cast和reinterpret_cast仍然不同。 如果基類和派生類的大小不同,則指向同一對象的基類指針和派生類指針可能具有不同的地址-如果存在虛擬表。

請參閱: 關於動態轉換以及基礎對象和派生對象的地址

如果沒有虛擬方法,則static_cast將執行->編譯時間轉換(執行速度更快)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM