指向抽象基类的指针需要一些强制转换吗?C++

pointer to abstract base class need some cast? C++

本文关键字:转换 C++ 抽象 基类 指针      更新时间:2023-10-16

>我有2个类:

class MyAbstractClass
{
public:
 virtual const std::string& getStr() const =0;
}
class MyRealClass : public MyAbstractClass
{
public: 
virtual const std::string& getStr() const { return m_str;};
private:
std::string m_str;
}

我主要有:

MyAbstractClass* ptr = new(MyRealClass("some string"));

我想通过指向基类的指针获取存储在MyRealClass中的字符串信息。我是否需要以某种方式ptr投射到MyRealClass以获取信息?或者运行时环境将足够智能,可以弄清楚我实际上是在从MyRealClass调用getStr

ptr->getStr(); 或者其他类似static_cast<MyRealClass*>(ptr)->getStr();甚至dynamic_cast<MyRealClass*>(ptr)->getStr();的东西?

一般来说,如果我们使用指向 Abstract 基类的指针,而不仅仅是指向简单(真正的)基类,我们实际上是否需要强制转换?

你想要的是所谓的多态性,它是面向对象编程语言(如C++)的一个特性。

要使方法多态,您必须将其标记为虚拟(就像您在示例中使用 getStr() 所做的那样),只要您的方法是虚拟的,您就可以在派生类中覆盖它们,如果您从基类指针调用这些方法,它将调用您实例化的类的版本(在您的示例中为 MyRealClass)。如果您不将它们标记为虚拟,它们将从您拥有的指针类型调用方法的版本。(如果您想了解更多有关该主题的信息,请搜索"虚拟表","虚拟调度"和"后期绑定")

请注意,当您编写:

virtual void someMethod() = 0;

正在声明所谓的纯虚拟方法,因为它们没有自己的实现,因此您被迫在派生类中定义它们(这就是接口和抽象类在C++中制作的方式)。

要从派生类转换为基类,您可以使用 static_cast ,尽管编译器足够聪明,可以自己完成(无需实际进行强制转换)。所以这就足够了:

MyAbstractClass* ptr = new(MyRealClass("some string"));

但是,在您的情况下,基类没有虚拟析构函数,删除时得到的是未定义的行为。


如果你想从基础转换为派生 - static_cast是不够的。然后你需要使用dynamic_cast,并检查它是否成功。

否;您可以通过抽象类调用指向抽象基类子类的指针成员。尽管您显示的代码示例不完整。

向接口添加一个虚拟析构函数,为具体类添加一个构造函数,以及清理一些分号 - 我们得到:

#include<string>
class MyAbstractClass{
public:
  virtual const std::string& getStr() const = 0;
  virtual ~MyAbstractClass(){}
};
class MyRealClass : public MyAbstractClass{
public:
  MyRealClass(std::string str) :
    m_str(str)
  {}
  virtual const std::string& getStr() const{ 
    return m_str;
  }
private:
  std::string m_str;
};

现在,调用MyAbstractClass* ptr = new MyRealClass("some string");将允许ptr->getStr()返回"一些字符串"。