Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这里适合哪种类型的演员?_C++_Oop_Templates - Fatal编程技术网

C++ 这里适合哪种类型的演员?

C++ 这里适合哪种类型的演员?,c++,oop,templates,C++,Oop,Templates,我有一个名为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

我有一个名为
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;
};
模板
类BaseNode
{
公众:
T*addChildNode(常量字符*名称);
void deleteChildNode(常量字符*名称);
void deleteAllChildNodes();
T*findFirstNode(常量字符*名称);
T*getChildNode(常量字符*名称);
T*getChildNode(无符号整数索引);
无效集合名(常量字符*名称);
无效设置转换(常量glm::mat4和转换);
unsigned int getNumChildren()常量{return\u children.size();}
const char*name()const{return_name.c_str();}
T*parent()常量{return\u parent;}
常量glm::mat4&transformation()常量{return\u transformation;}
常量glm::mat4&torootttransformation()常量{return\u toRoot;}
受保护的:
BaseNode(常量字符*节点名,T*父节点);
虚拟~BaseNode();
std::string _name;
glm::mat4_变换;
glm::mat4_-toRoot;
T*_父母;
性病:病媒儿童;
};
这个类的功能是我可以创建自己类型的“节点类”,然后它们将继承这个类模板的所有场景图方法。(例如
classmynode:publicbasenode{…};

addChildNode(const char*name)
函数插入一个
newt(name,this)
到子向量,当
这个
应该是子向量的父向量时。编译器抛出一个强制转换错误,并建议我为此使用某种强制转换。我目前正在使用
动态\u强制转换
,但这确实让我感到困扰,因为我认为它没有用


我的问题是,在这种情况下,使用reinterpret\u cast(基本上与C-cast类似)是否安全:
\u children.push\u back(新的T(名称,reinterpret\u cast(this)))因为IMO dynamic_cast永远不会失败。

dynamic_cast和reinterpret_cast仍然不同。如果基类和派生类的大小不同,则基类指针和指向同一对象的派生类指针可能具有不同的地址-如果存在虚拟表

见:


如果没有虚拟方法,静态_转换将执行->编译时转换(执行速度更快).

动态转换和重新解释转换仍然不同。如果基类和派生类的大小不同,则基类指针和指向同一对象的派生类指针可能具有不同的地址(如果存在虚拟表)

见:


如果没有虚拟方法,静态_转换将执行->编译时转换(执行速度更快).

动态转换和重新解释转换仍然不同。如果基类和派生类的大小不同,则基类指针和指向同一对象的派生类指针可能具有不同的地址(如果存在虚拟表)

见:


如果没有虚拟方法,静态_转换将执行->编译时转换(执行速度更快).

动态转换和重新解释转换仍然不同。如果基类和派生类的大小不同,则基类指针和指向同一对象的派生类指针可能具有不同的地址(如果存在虚拟表)

见:


如果没有虚拟方法,静态转换将执行->编译时转换(执行速度更快)。

静态转换是正确的。
动态_cast比您需要的慢得多。
重新解释转换不正确。您不知道派生对象的基类部分与派生对象在同一位置开始。如果需要,静态转换将调整地址。重新解释转换不正确。

静态转换正确。
动态_cast比您需要的慢得多。
重新解释转换不正确。您不知道派生对象的基类部分与派生对象在同一位置开始。如果需要,静态转换将调整地址。重新解释转换不正确。

静态转换正确。
动态_cast比您需要的慢得多。
重新解释转换不正确。您不知道派生对象的基类部分与派生对象在同一位置开始。如果需要,静态转换将调整地址。重新解释转换不正确。

静态转换正确。
动态_cast比您需要的慢得多。 reinterpret\u cast不正确。您不知道派生对象的基类部分与派生对象的起始位置相同。如果需要,静态cast会调整地址。reinterpret\u cast不会调整地址。

这是这里惯用的so
静态cast的一个示例

在这种情况下,可以通过多种方式避免强制转换。最简单的方法是将构造函数更改为:

BaseNode(const char* nodeName, T* parent, T* thisAsT);
并添加一个适当的字段:

//...
T* _parent;
T* _thisAsT;
因此,在
addChildNode
中,您可以轻松访问
指针,并使用适当的类型:

_children.push_back(new T(name, _thisAsT));
当然,这需要派生类在其构造函数中为此参数提供有效指针


然而,另一个有点笨拙的问题是添加:

virtual T* buildFromName(const char* name) = 0;
然后在
addChildNode
中使用它:

_children.push_back(buildFromName(name));
但是,这要求派生类为其自己的类型实现工厂方法,例如,这违反了。另一方面,为每个派生类创建工厂类型似乎有点过火


第二个想法,具有与上述类似的特性:

virtual T* getThis() = 0;
然后:

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

少数旁注:

-考虑使用<代码> STD::String 而不是<代码> const char */COD>

-声明应该写成
T*x
而不是
T*x
(也应该是
const char*x
而不是
const char*x
)-星不是变量名称的一部分,它是类型说明符的一部分,所以应该在“类型端”

这是一个示例,因此
静态转换在这里是惯用的

在这种情况下,您可以通过多种方式避免强制转换