【问题标题】:pointer to abstract base class need some cast? C++指向抽象基类的指针需要一些转换吗? 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 语句中的一半括号,它的含义仍然相同。

标签: c++ pointers casting


【解决方案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() 返回“一些字符串”。

      【讨论】:

        猜你喜欢
        • 2015-08-12
        • 2010-12-02
        • 1970-01-01
        • 2013-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-17
        • 1970-01-01
        相关资源
        最近更新 更多