0

我有 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信息吗?还是运行时环境足够聪明,可以确定我实际上是从哪里调用getStrMyRealClass

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

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

4

3 回答 3

2

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

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

请注意,当您编写时:

virtual void someMethod() = 0;

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

于 2013-11-09T19:32:10.187 回答
0

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

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

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


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

于 2013-11-09T19:26:12.847 回答
0

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

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

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

于 2013-11-09T19:37:06.070 回答