指向抽象基类的指针需要一些转换吗? 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->getStr()
返回“一些字符串”。
【讨论】:
以上是关于指向抽象基类的指针需要一些转换吗? C++的主要内容,如果未能解决你的问题,请参考以下文章