C++ 我们可以在不知道其实际类型的情况下将基类指针转换为派生类指针吗?

C++ 我们可以在不知道其实际类型的情况下将基类指针转换为派生类指针吗?,c++,C++,如果我有一个基类a和2个派生类B和C,有没有一种简单的方法可以在不知道其真实类型的情况下将指针a*转换为B*或C*?在不切换typeid的情况下。问题是:您需要在编译时知道每个变量的类型。因此,不能有一个神奇的函数f,它接受a*a,并根据a指向的对象的实际类型的运行时信息返回B*或C*。即使对于下面的示例,也将调用函数B::f,但返回类型将是A*类型,因为这是在编译时确定的 包括 结构A{ 虚拟A*获取ptr{std::cout问题是:您需要在编译时知道每个变量的类型。因此,您不能有一个神奇的函

如果我有一个基类a和2个派生类B和C,有没有一种简单的方法可以在不知道其真实类型的情况下将指针a*转换为B*或C*?在不切换typeid的情况下。

问题是:您需要在编译时知道每个变量的类型。因此,不能有一个神奇的函数f,它接受a*a,并根据a指向的对象的实际类型的运行时信息返回B*或C*。即使对于下面的示例,也将调用函数B::f,但返回类型将是A*类型,因为这是在编译时确定的

包括 结构A{
虚拟A*获取ptr{std::cout问题是:您需要在编译时知道每个变量的类型。因此,您不能有一个神奇的函数f,它接受a*a,并根据a指向的对象的实际类型的运行时信息返回B*或C*。即使对于以下示例,函数B::f也将被调用,但返回类型是将为A*类型,因为这是在编译时确定的

包括 结构A{
虚拟的A*get_ptr{std::cout有点不神圣,但我看到:

   class B;
   class C;

   class A {
   public :
     virtual B* getAsB() { return nullptr; }
     virtual C* getAsC() { return nullptr; }
   }

   class B : public A {
   public:
     B* getAsB() override { return this; }
   }

   class C : public A {
   public:
     C* getAsC() override { return this; }
   }
解决这个问题的一种更为指令缓存友好的方法是,按类型对对象进行排序,然后使用知道它处理的类型的代码遍历所有的B,然后遍历所有的C。是的,指令有自己的缓存行,通过大型对象层次结构的虚拟函数到处乱动并不是一种很好的避免方法缓存未命中。当然,如果您的调用堆栈足够深,那就无关紧要了

OOD和cache的友好性常常是不一致的


哎呀,这是所有的说教。OOD通常都很好,直到你的性能要求达到11,我在关注你的游戏行业。

这有点不神圣,但我看到:

   class B;
   class C;

   class A {
   public :
     virtual B* getAsB() { return nullptr; }
     virtual C* getAsC() { return nullptr; }
   }

   class B : public A {
   public:
     B* getAsB() override { return this; }
   }

   class C : public A {
   public:
     C* getAsC() override { return this; }
   }
解决这个问题的一种更为指令缓存友好的方法是,按类型对对象进行排序,然后使用知道它处理的类型的代码遍历所有的B,然后遍历所有的C。是的,指令有自己的缓存行,通过大型对象层次结构的虚拟函数到处乱动并不是一种很好的避免方法缓存未命中。当然,如果您的调用堆栈足够深,那就无关紧要了

OOD和cache的友好性常常是不一致的


Yikes,这是所有的说教。OOD通常是好的,直到你的性能要求被拨到11。我正在关注你的游戏行业。

动态施法是唯一安全的方法,不需要提前知道类型。为了避免动态施法,我有时会使用枚举来存储它的类型。简短回答:不。通常你应该使用多态o您不需要知道类型。您可以使用DyANMICECAST并检查基指针实际上包含派生类对象的对象是否一致,DyrimeCype是唯一的方法,并且我认为它是最后一个RealtNoPE的一个特征。通常使用枚举来存储它的类型。简短的回答是:不,通常你应该使用多态性,这样你就不需要知道类型。你可以使用DyANMICECAST并检查一个基指针实际上包含一个派生类对象的对象是否一致,DyrimeCype是唯一的方法,我认为它是最后一个RealTunPoT的一个特性。至少是不安全的。你确定吗?这是可行的?我假设你在a中需要一对虚拟体。之后,如果我没有弄错的话,它应该与dynamic_cast完全相同。Derp,最近太多Java。修复了。还添加了覆盖。是的,它与dynamic cast类似,但是你可以关闭RTTI,只为选择的类手动添加它。这总体上比较便宜,但是c创建了潜在的bug。我没有看到其中的一个bug,但我在这里看到的代码库在我到达时已经相当成熟。我还看到了一些实例,其中有并行const版本返回const B*和const C*。我希望C++23包含与starship操作符等价的const。这是一个任意const版本返回一个任意常量类型的函数。你确定这有效吗?我假设你在a中需要一对虚拟体。如果我没有弄错的话,它应该与dynamic_cast完全相同。Derp,太多Java了。修复了。还添加了覆盖。是的,它与dynamic cast一样工作,但是你可以关闭RTTI,只需要一个为选定的类手动添加它。这总体上比较便宜,但可能会产生错误。我还没有看到这些错误中的任何一个,但我在这里看到的代码库在我到达时非常成熟。我还看到过并行const版本返回const B*和const C*。我希望看到C++23包含const equivale这是函数的任意常量版本,返回一个任意常量类型。挑剔:对象的类型不是n
需要在编译时知道。。这就是对象动态类型的全部要点。当然,您需要知道用于在编译时访问对象的变量的类型。是的,您当然是对的。我觉得用语言表达这个想法有点困难。我做了一点修改,希望能让它更清楚。挑剔:编译时不需要知道对象的类型。。这就是对象动态类型的全部要点。当然,您需要知道用于在编译时访问对象的变量的类型。是的,您当然是对的。我觉得用语言表达这个想法有点困难。我改变了一点,希望这能让事情变得更清楚。