c++父类和子类的用法
C++ Parent and Child class usage
假设我有一个Person
类。这个person类包含一个Shape
。
Shape
父类有几个子类派生自它。例如Rectangle
和Circle
。每个子类都有自己的方法。例如Circle类有GetRadius()
,而Rectangle类有GetWidth()
和更多针对这种形状的方法。
现在假设有几个人,其中一些人持有矩形,另一些人持有圆形。我想知道每个人的手是什么形状,我想从这些形状中得到信息。但是我不能这样做,因为Person持有一个Shape,所以它不能访问任何子特定的方法。
我读了一些关于铸造的东西,但我发现它有点令人困惑,我不确定铸造是否会是最好的方式来做到这一点,或者是否有一个更efficiënt的方式去做这个完全。我该怎么做呢?
编辑1:编辑更多的澄清。我希望GetWidth()
和GetRadius()
等方法返回不同的类型。
由于Shape
超类至少有一个虚方法,您当然可以使用dynamic_cast
来确定超类的每个实例是哪个子类。这当然是可能的,有时这样做是正确的,但大多数时候不是。
更确切地说,正确的做法是提前设计你的类,以一种方式,无论任何Shape
可能完成的操作,都有一个Shape
方法用于它,通常是虚拟的。最小的公分母是有一个由每个子类实现的纯虚方法,它返回特定子类所属的标识符。
但是,一般来说,如果您需要知道超类的实例的特定子类是什么,那么这是类层次结构设计不正确的线索。的确,生活并非总是100%完美的。有时,为了处理棘手的情况,可能有必要诉诸这种丑陋。但从一开始就不应该是这样。你应该尝试正确地设计你的类层次结构,这样就没有必要了。
即使是最小的公分母:
A)前面提到的返回超类所属特定子类的枚举标识符的函数,以及B)超类定义了所有超类都可以实现的所有可能的虚方法,默认实现会抛出异常
可以在不涉及难看的强制类型转换的情况下做到这一点。
如果你有一个类型为Shape
的指针,它包含子类型的对象,如Rectangle
或Circle
,那么你可以使用dynamic_cast
在运行时检查对象的类型。Dynamic_cast允许您安全地检查地址由指针保存的对象的运行时类型。
您可以通过在Shape
类上为适用于所有派生类的任何函数声明virtual
函数来避免强制类型转换的需要。在本例中,您想知道每个派生类型是什么,这样您就可以有一个getType()
函数。你不必完全这样做,但下面是一个例子,你可以这样做。
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Shape
{
public:
virtual ~Shape() {}
virtual Shape* clone() const = 0;
virtual std::string getType() const = 0;
};
class Circle : public Shape
{
public:
virtual Circle* clone() const override { return new Circle(*this); }
virtual std::string getType() const override { return "Circle"; }
};
class Rectangle : public Shape
{
public:
virtual Rectangle* clone() const override { return new Rectangle(*this); }
virtual std::string getType() const override { return "Rectangle"; }
};
class Person
{
public:
explicit Person(const std::string& name, const Shape& shape) :
mName(name),
mShape(shape.clone())
{
}
std::string mName;
std::unique_ptr<Shape> mShape;
};
int main()
{
std::vector<Person> people;
people.emplace_back("Foo", Circle());
people.emplace_back("Bar", Rectangle());
for (const auto& person : people)
{
std::cout << person.mName << " with " << person.mShape->getType() << "n";
}
return 0;
}
示例输出
Foo with Circle
Bar with Rectangle
<<p> 生活例子/kbd> - 继承期间显示未知行为的子类
- 通过指向指针数组的指针访问子类的属性
- 从父类方法返回子类对象
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 将父类对象强制转换为子类的问题
- 避免在C++中重复子类定义
- 将QOpenGLWidget子类转换为使用Metal而不是OpenGL的子类是否可行?
- 如何初始化矢量的模板化子类
- C++ 继承:将子类传递给需要基类的函数并获取子类行为
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 使用子类覆盖基类中定义的函数
- 子类地址等于虚拟基类地址?
- 将子类方法声明为基类的友元
- C++子类共享变量?
- 如何检查模板专用化是否是基本模板的子类?
- 仅让特定类'Fabric'构造类'Foo'及其所有子类的实例
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 如何在C++子类中访问父类的私有变量
- c++父类和子类的用法