c++ - 将对象声明为抽象类
问题描述
编辑最初发布的这个问题是我所拥有的简化版本,因此不包含导致错误的问题。我已经更新为更像我的问题,并且会发布答案以防其他人遇到类似问题。
在 C++ 中是否可以将对象声明为抽象类,然后将其实例化为派生类?
以这个修改版本的示例代码为例,从https://www.tutorialspoint.com/cplusplus/cpp_interfaces.htm获得
class Shape {
public:
// pure virtual function providing interface framework.
virtual int getArea() = 0;
virtual int getNumOfSides() = 0;
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
// Derived classes
class Rectangle: public Shape {
public:
int getArea() {
return (width * height);
}
};
class Triangle: public Shape {
public:
int getArea() {
return (width * height)/2;
}
};
int main(void) {
Rectangle Rect;
Triangle Tri;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object.
cout << "Total Rectangle area: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
// Print the area of the object.
cout << "Total Triangle area: " << Tri.getArea() << endl;
return 0;
}
但是,如果我们在编译时不知道 Shape 的类型,是否可以执行以下操作:
Shape *shape;
if (userInput == 'R') {
shape = new Rectangle();
} else if (userInput == 'T') {
shape = new Triangle();
}
// etc.
... 可以在 C# 中完成吗?
我已经尝试过了,但得到了错误:
错误:抽象类类型“矩形”的无效新表达式
这是在 QT 内。
解决方案
在 C++ 中是否可以将对象声明为抽象类,然后将其实例化为派生类?
你不能声明一个对象,不。抽象类不能被实例化。但是,您可以声明一个指向实现抽象类的对象的引用/指针,是的。例如:
Shape *shape;
if (userInput == 'R') {
shape = new Rectangle();
} else if (userInput == 'T') {
shape = new Triangle();
}
// etc.
delete shape;
在 C++11 及更高版本中,当指针超出范围时,您可以使用std::unique_ptr
orstd::shared_ptr
自动调用,例如:delete
std::unique_ptr<Shape> shape;
if (userInput == 'R') {
shape.reset(new Rectangle);
// or: shape = std::unique_ptr<Shape>(new Rectangle);
// or: shape = std::make_unique<Rectangle>(); // C++14 and later only
} else if (userInput == 'T') {
shape.reset(new Triangle);
// or: shape = std::unique_ptr<Shape>(new Triangle);
// or: shape = std::make_unique<Triangle>(); // C++14 and later only
}
// etc.
std::shared_ptr<Shape> shape;
if (userInput == 'R') {
shape.reset(new Rectangle);
// or: shape = std::make_shared<Rectangle>();
} else if (userInput == 'T') {
shape.reset(new Triangle);
// or: shape = std::make_shared<Triangle>();
}
// etc.
无论哪种方式,只要确保它Shape
有一个virtual
析构函数,以便在通过指针delete
'ing 派生对象时调用正确的派生析构函数:Shape*
class Shape {
public:
virtual ~Shape() {}
// ...
};
推荐阅读
- selenium - 如何使用 selenium 处理表
- sql - 如何在分配参数后但在打开之前记录 SQL.text
- android - Rocket.Chat - 从另一个应用程序开始火箭聊天
- ruby-on-rails - wicked_pdf 我想解决heroku和本地环境显示大小不同的问题
- r - 如何使用shinydashboard的材质切换[R]
- java - Java jdom 不打印所有元素,打印空字符串
- r - 我在 R 中导入的 .csv 中的第一列以 0 开头,我想更改它
- angular - Angular 4 - 使用 .htaccess 重定向到 https 时出现错误 404
- typescript - 带有未定义可变参数的打字稿回调
- react-admin - 如何在 react-admin 的另一个组件中显示 ImageInput src?