C++ 使用基类指针调用派生类中的非虚函数

C++ 使用基类指针调用派生类中的非虚函数,c++,polymorphism,C++,Polymorphism,如图所示: 高度依赖dynamic_cast通常表明您的设计出了问题 我想知道的是,如何在派生类中调用自定义函数,基类中没有相同名称的函数,但使用基类指针调用,如果事实上有更好的方法,可能不使用dynamic\u cast 如果这个函数是在两者中定义的虚拟函数,那么这很容易。但这只是派生类中的唯一函数 也许dynamic\u cast毕竟是最好的方法?为了调用Derived类的函数,您必须获得指向派生类的指针。作为一种选择(取决于情况),您可能希望使用静态\u cast而不是动态,但正如您所说:

如图所示:

高度依赖dynamic_cast通常表明您的设计出了问题

我想知道的是,如何在派生类中调用自定义函数,基类中没有相同名称的函数,但使用基类指针调用,如果事实上有更好的方法,可能不使用
dynamic\u cast

如果这个函数是在两者中定义的虚拟函数,那么这很容易。但这只是派生类中的唯一函数


也许
dynamic\u cast
毕竟是最好的方法?

为了调用
Derived
类的函数,您必须获得指向派生类的指针。作为一种选择(取决于情况),您可能希望使用
静态\u cast
而不是
动态
,但正如您所说:

这通常表明您的设计出了问题

此外,有时我认为使用强制类型转换也可以。当我为游戏设计GUI库时,它有一个基类
Widget
和许多子类。在编辑器中创建了一个实际的窗口布局,后来一些
加载程序
类扩展了这个布局。为了用每个小部件的实际特定数据(与游戏相关)填充布局中的小部件,我制作了一个从小部件查询小部件的子部件的方法。此函数重新调整了
小部件*
,然后I
动态地将其转换为实际类型。我还没有找到更好的设计


后来我还发现
Android
上的GUI系统的工作方式与之相同

为了调用
Derived
类的函数,您必须获得指向派生类的指针。作为一种选择(取决于情况),您可能希望使用
静态\u cast
而不是
动态
,但正如您所说:

这通常表明您的设计出了问题

此外,有时我认为使用强制类型转换也可以。当我为游戏设计GUI库时,它有一个基类
Widget
和许多子类。在编辑器中创建了一个实际的窗口布局,后来一些
加载程序
类扩展了这个布局。为了用每个小部件的实际特定数据(与游戏相关)填充布局中的小部件,我制作了一个从小部件查询小部件的子部件的方法。此函数重新调整了
小部件*
,然后I
动态地将其转换为实际类型。我还没有找到更好的设计

后来我还发现
Android
上的GUI系统也是这样工作的

我想知道的是如何在派生类中调用自定义函数。。。如果事实上有更好的方法,则不使用
动态\u cast

正如报价中所指出的,这是一个设计问题,而不是实现问题。没有“更好的方法”来调用该函数;“更好的方法”是重新设计类型,这样子类型就不需要向其父类型添加功能。通过这样做,您的类型满足(一种常见的解释)Liskov替换原则,并且更易于使用,因为用户根本不需要知道子类型

如果以这种方式重新设计类型是不可能的或不合理的困难,那么您可能确实需要RTTI。该建议没有说“全部使用…”,只是说“高度依赖…”,这意味着RTTI应该是最后的手段,而不是默认的方法

我想知道的是如何在派生类中调用自定义函数。。。如果事实上有更好的方法,则不使用
动态\u cast

正如报价中所指出的,这是一个设计问题,而不是实现问题。没有“更好的方法”来调用该函数;“更好的方法”是重新设计类型,这样子类型就不需要向其父类型添加功能。通过这样做,您的类型满足(一种常见的解释)Liskov替换原则,并且更易于使用,因为用户根本不需要知道子类型


如果以这种方式重新设计类型是不可能的或不合理的困难,那么您可能确实需要RTTI。建议没有说“全部使用…”,只是说“高度依赖…”,这意味着RTTI应该是最后的手段,而不是默认的方法。

这更像是一种选择,而不是真正的答案,所以不要用石头打死我

class Derived;

class Base
{
public:

   virtual Derived * getDerived()const
   {
       return NULL;
   }
};

class Derived : public Base
{
public:

   virtual Derived * getDerived()const
   {
       return this;
   }
};
我想你明白了


迈克·西摩,谢谢:-)

这更像是一个选择,而不是一个真正的答案,所以不要用石头打死我

class Derived;

class Base
{
public:

   virtual Derived * getDerived()const
   {
       return NULL;
   }
};

class Derived : public Base
{
public:

   virtual Derived * getDerived()const
   {
       return this;
   }
};
我想你明白了


p.S.迈克·西摩,谢谢:-)

事实上,你想做你想做的事,这是你的设计可以通过返工来完成的标志。如果您需要这样做,请使用
dynamic\u cast
。可能只有我一个人,但我怀疑您的设计有点错误。出于兴趣,什么样的场景需要您这样做?如果您确实想这样做,您应该问自己,在您想这样做的时候,您是否真的处理了正确的类型。如果代码设计为与基类一起工作,那么您应该与基类一起工作,如果您到处都要问“可能是这种类型,那么就这样做”这只是您工作的错误类型级别。@Muckle_-ewe:最有可能的情况是,如果您使用基类指针导航到一个对象,然后需要做一些不通过基类公开的事情。RTTI是解决这个问题的一个选项,其他选项是胖基类、访问者模式或导航方案的重新设计。事实上,你想做你想做的事情,这是你的设计可以通过返工来完成的标志。如果您需要这样做,请使用
dynamic\u cast
。也许只有我一个人,但我怀疑您的设计有点错误。出于兴趣,什么样的场景需要您这样做?如果您真的想这样做,您应该问自己,在您想这样做的时候,您是否真的处理了正确的问题