Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.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++ 使用static_cast处理混合(基本和派生)对象的向量是否存在性能风险?(又名“这是一个愚蠢的想法吗?”)_C++_Vector_Static Cast - Fatal编程技术网

C++ 使用static_cast处理混合(基本和派生)对象的向量是否存在性能风险?(又名“这是一个愚蠢的想法吗?”)

C++ 使用static_cast处理混合(基本和派生)对象的向量是否存在性能风险?(又名“这是一个愚蠢的想法吗?”),c++,vector,static-cast,C++,Vector,Static Cast,给定一个基类gameObject和一个派生类animatedGameObject,我认为最好将它们的所有实例存储在std::vector中。如果向量GameObjects被声明为gameObject*的基本类型,则派生对象实例需要强制转换 例如: vector<gameObject*> GameObjects; gameObject A* = new gameObject( ...init... ); animatedGameObject B* = new animatedGam

给定一个基类
gameObject
和一个派生类
animatedGameObject
,我认为最好将它们的所有实例存储在
std::vector
中。如果向量
GameObjects
被声明为
gameObject*
的基本类型,则派生对象实例需要强制转换

例如:

vector<gameObject*> GameObjects;

gameObject A* = new gameObject( ...init... ); 
animatedGameObject B* = new animatedGameObject( ...init... );

GameObjects.push_back(A);
GameObjects.push_back(B);

// to access the animatedGameObject functions:
static_cast<animatedGameObject*>(GameObjects[1])->functionUniqueToAnimated();
矢量游戏对象;
游戏对象A*=新游戏对象(…初始化…);
animatedGameObject B*=新的animatedGameObject(…初始化…);
游戏对象。推回(A);
游戏对象。推回(B);
//要访问animatedGameObject函数,请执行以下操作:
静态_cast(GameObjects[1])->functionUniqueToAnimated();
我像往常一样害怕,我转向Scott Meyers(有效C++,第三版),他写的主题是:

许多程序员相信cast只会告诉编译器将一种类型视为另一种类型,但这是错误的。任何类型的类型转换(通过强制转换显式转换或由编译器隐式转换)通常都会导致在运行时执行代码

我已经阅读了他的第27条:最小化施法两次,但鉴于我在这方面的经验不足,我无法回答一个简单的问题“这是一件愚蠢的事情吗?”

我应该提到,有几个原因可以解释为什么这样做是愚蠢的,而与调用
静态\u cast
无关。这些问题按重要性排列如下:

  • 在我上面的示例中,我是否没有看到使用
    静态\u cast
    可能存在的风险
  • 对于这种方法,是否有比std::vector更好的数据结构?(除非有一个是显而易见的,否则我不是要你替我做研究。)

  • 这是我第一次在这里问问题,所以如果有必要,请提前道歉。

    static\u cast
    不是适合这项工作的工具,除非您知道指针指向的是
    animatedGameObject
    而不是
    游戏对象。您使用什么数据结构来存储这些信息

    在基指针之后确定派生对象的类型是动态分派或
    dynamic\u cast
    的工作。在您的示例中,调用
    GameObjects[1]->draw()
    应该不使用强制转换,因为
    draw
    应该是一个虚拟函数。否则,您可以使用
    dynamic\u cast(*GameObjects[1])
    断言该对象是animatedGameObject,如果不是,则抛出
    std::bad\u cast
    异常。(这仍然需要
    类游戏对象
    中的
    虚拟
    函数,通常是其析构函数。)

    但是对多态派生类型执行
    静态\u cast
    是一种代码味道


    您还询问
    std::vector
    是否是该用例的良好数据结构。它是,但不是“裸”指针的向量。C++11现在提供了“智能指针”内存管理类,这些类为您执行
    new
    delete
    ,使实际的操作符几乎过时。查看此案例的
    std::unique_ptr

  • 若gameObjects[1]不是animatedGameObject,那个么应用程序(很可能)会可怕地死去
  • 如果draw()是gameObject中存在的虚拟方法,则不需要进行转换
  • 通常,将基类强制转换为派生类是不安全的。在这些情况下,使用动态_cast是有意义的。如果无法执行转换,则Dynamic_cast返回NULL

    是否有比现有数据结构更好的数据结构


    好吧,如果你的游戏对象没有在其他地方自动删除,那么使用类似于
    std::vector
    的东西可能是有意义的。然而,标准共享指针可能会引入隐藏的开销(额外的new/delete,在最坏的情况下,如果它们被设计为线程安全的,它们甚至可能引入多线程互斥锁),因此,您应该确保这些开销与您的目标兼容。

    +1要阅读有效的C++,这里通常要做的事情是将
    draw()
    定义为基类中的虚拟函数。然后,您可以简单地调用它,而不使用强制转换,这样做是正确的。你知道这一点,但想知道演员的具体效果吗?是的,我应该使用一个更好的函数名,对你评论末尾的问题回答是。你如何知道
    [1]
    包含动画对象?我的意思是在你的代码的真实版本中。通常,这些信息可以被移动到程序结构中,或者被利用来更好地打包演员阵容,或者消除它。我将再次投票/提高可见性,使
    draw
    虚拟化,这样就可以不用演员阵容了。这是虚拟函数基本上完美工作的经典例子之一。@jogojapan D'oh,我自己也弄糊涂了。自定义删除程序可以使
    唯一\u ptr
    以多态方式处理非多态类型。我会修好的。非常感谢。去读一下
    std::shared_ptr
    @ilya我犯了一个错误,
    std::unique_ptr
    如果没有任何高级技术就可以了。我一直在想别的事情:让非多态类型以多态的方式行为。