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

Posted

技术标签:

【中文标题】指向抽象基类的指针需要一些转换吗? C++【英文标题】:pointer to abstract base class need some cast? C++ 【发布时间】:2013-11-09 19:22:08 【问题描述】:

我有两门课:

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(); 的东西?

一般来说,如果我们使用一个指向抽象基类的指针,而不仅仅是一个简单的(真正的)基类,我们真的需要强制转换吗?

【问题讨论】:

您尝试过这些替代方案吗?有没有工作?有没有失败? 提问前请先编译好你的代码! 请注意,您可以删除new 语句中的一半括号,它的含义仍然相同。 【参考方案1】:

你想要的是一种叫做多态性的东西,它是面向对象编程语言(例如C++)的一个特性。

要使方法具有多态性,您必须将其标记为虚拟(就像您在示例中使用 getStr() 所做的那样),只要您的方法是虚拟的,您就可以在派生类中覆盖它们,并且如果您调用这些方法从基类指针它将调用您实例化的类的版本(在您的示例中为 MyRealClass)。如果您不将它们标记为虚拟,它们将根据您拥有的指针类型调用该方法的版本。 (如果您想了解更多主题,请搜索“Virtual table”、“virtual dispatch”和“late binding”)

注意写的时候:

virtual void someMethod() = 0;

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

【讨论】:

【参考方案2】:

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

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

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


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

【讨论】:

【参考方案3】:

没有;您可以通过抽象类调用指向抽象基类子级的指针的成员。虽然您展示的代码示例不完整。

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

#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-&gt;getStr() 返回“一些字符串”。

【讨论】:

以上是关于指向抽象基类的指针需要一些转换吗? C++的主要内容,如果未能解决你的问题,请参考以下文章

基类的函数指针指向子类的成员函数?

C++类体系中this指针不能改变指向吗?

c++工厂模式

c++工厂模式

如果继承类型受到保护,我可以使基类的指针指向派生对象吗? [复制]

指向派生对象的基类指针的 C++ 排序容器