【发布时间】:2021-06-10 17:45:33
【问题描述】:
编辑最初发布的这个问题是我所拥有的问题的简化版本,因此不包含导致错误的问题。我已经更新为更像我的问题,并且会发布答案以防其他人遇到类似问题。
在 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 内。
【问题讨论】:
-
Shape* shape; -
在 C# 中,像
shape这样的标识符基本上是一个智能指针。在 C++ 中,对象的实例和指向对象的指针之间有一个非常重要的区别。Shape shape;试图定义一个完整的Shape对象,它不能(它是抽象的)。你想要一个指向Shape的指针。请考虑使用std::unique_ptr<Shape> shape;。 -
哪个编译器给了你这个错误?这很奇怪,因为
Rectangle不是抽象的。当我尝试它时,我得到了相当不同的错误消息:error: cannot declare variable 'shape' to be of abstract type 'Shape'(定义shape时预期)和error: no match for 'operator=' (operand types are 'Shape' and 'Rectangle*')(分配new Rectangle时)和error: no match for 'operator=' (operand types are 'Shape' and 'Triangle*')(分配new Triangle时)。后面的消息中的星号非常重要。 -
抱歉,我应该包含细节,这是 QT,我已将其声明为指针 - 我已经编辑了帖子。
-
我要坦白,我没有发布完整的代码,这是一个高度简化的版本,为了避免共享机密代码和简单起见。实际的代码是不同的,并且包含了一个没有的问题,这使得这个问题无法回答。
标签: c++ qt oop abstract-class