我有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
以获取信息吗?或者运行时环境是否足够智能,以确定我实际上是从getStr
调用MyRealClass
?
ptr->getStr();
或其他类似static_cast<MyRealClass*>(ptr)->getStr();
甚至dynamic_cast<MyRealClass*>(ptr)->getStr();
的内容?
一般情况下,如果我们使用指向Abstract基类的指针,而不仅仅是简单(真实)基类,我们是否真的需要强制转换?
答案 0 :(得分:2)
你想要的是一种叫做 Polymorphism 的东西,它是面向对象编程语言(如C ++)的一个特性。
要使方法具有多态性,您必须将其标记为虚拟(就像您在示例中使用getStr()一样),只要您的方法是虚拟的,您可以在派生类中覆盖它们,并且如果您调用这些方法从基类指针,它将调用您实例化的类的版本(在您的示例中为MyRealClass)。如果您不将它们标记为虚拟,则它们将从您拥有的指针类型调用该方法的版本。 (如果您想了解有关该主题的更多信息,请搜索“虚拟桌面”,“虚拟调度”和“后期绑定”)
请注意,当你写:
virtual void someMethod() = 0;
您正在声明所谓的纯虚方法,因为它们没有自己的实现,您不得不在派生类中定义它们(这就是如何在C ++中创建接口和抽象类)。
答案 1 :(得分:0)
要从派生类转换为基类,可以使用static_cast
,尽管编译器足够聪明,可以自己完成(不需要实际执行转换)。所以这就足够了:
MyAbstractClass* ptr = new(MyRealClass("some string"));
但是,在您的情况下,您的基类没有虚拟析构函数,删除时获得的是未定义的行为。
如果你想从base转换为派生 - static_cast是不够的。然后你需要使用dynamic_cast,并检查它是否成功。
答案 2 :(得分: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()
返回“某些字符串”。