将对象声明为抽象对象 class
Declare an object as abstract class
编辑 这个问题最初 posted 是我所拥有的简化版本,因此不包含导致错误的问题。我已更新为更像我的问题,如果其他人有类似问题,我会 post 一个答案。
在 C++ 中是否可以将对象声明为抽象对象 class,然后将其实例化为派生对象 class?
使用示例代码的修改版本,从 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# 中完成吗?
我试过了,但出现错误:
error: invalid new-expression of abstract class type 'Rectangle'
这是在QT内。
如果你想保持你的程序内存安全,你可以这样使用std::shared_ptr
:
#include <memory>
template <class T>
using ptr = std::shared_ptr<T>;
class Shape { ... };
class Rectangle: public Shape { ... };
class Triangle: public Shape { ... };
int main()
{
ptr Rect = std::make_shared<Rectangle>();
ptr Tri = std::make_shared<Triangle>();
// Notice you have to use '->' instead of '.', since those are (smart) pointers
Rect->setWidth(5);
Rect->setHeight(7);
cout << "Total Rectangle area: " << Rect->getArea() << endl;
Tri->setWidth(5);
Tri->setHeight(7);
cout << "Total Triangle area: " << Tri->getArea() << endl;
// Can't use CTAD as for Rect and Tri. We have to specify 'Shape'.
ptr<Shape> shape;
char userInput;
std::cin >> userInput;
if (userInput == 'R') {
shape = std::make_shared<Rectangle>();
} else if (userInput == 'T') {
shape = std::make_shared<Triangle>();
}
cout << shape->getArea() << endl;
return 0;
}
In C++ is it possible to declare an object as an abstract class, but then instantiate it to a derived class?
你不能声明一个对象,不。无法实例化抽象 classes。但是,您可以声明一个 reference/pointer 到实现抽象 class 的对象,是的。例如:
Shape *shape;
if (userInput == 'R') {
shape = new Rectangle();
} else if (userInput == 'T') {
shape = new Triangle();
}
// etc.
delete shape;
在C++11及之后的版本中,你可以使用std::unique_ptr
or std::shared_ptr
在指针超出作用域时自动为你调用delete
,eg:
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
时将调用正确的派生析构函数20=]指针:
class Shape {
public:
virtual ~Shape() {}
// ...
};
问题是抽象 class 定义的虚函数中并非 所有 都在派生的 classes 中实现。
我需要
// Derived classes
class Rectangle: public Shape {
public:
int getArea() {
return (width * height);
}
int getNumOfSides() {
return 4;
}
};
class Triangle: public Shape {
public:
int getArea() {
return (width * height)/2;
}
int getNumOfSides() {
return 3;
}
};
编辑 这个问题最初 posted 是我所拥有的简化版本,因此不包含导致错误的问题。我已更新为更像我的问题,如果其他人有类似问题,我会 post 一个答案。
在 C++ 中是否可以将对象声明为抽象对象 class,然后将其实例化为派生对象 class?
使用示例代码的修改版本,从 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# 中完成吗?
我试过了,但出现错误:
error: invalid new-expression of abstract class type 'Rectangle'
这是在QT内。
如果你想保持你的程序内存安全,你可以这样使用std::shared_ptr
:
#include <memory>
template <class T>
using ptr = std::shared_ptr<T>;
class Shape { ... };
class Rectangle: public Shape { ... };
class Triangle: public Shape { ... };
int main()
{
ptr Rect = std::make_shared<Rectangle>();
ptr Tri = std::make_shared<Triangle>();
// Notice you have to use '->' instead of '.', since those are (smart) pointers
Rect->setWidth(5);
Rect->setHeight(7);
cout << "Total Rectangle area: " << Rect->getArea() << endl;
Tri->setWidth(5);
Tri->setHeight(7);
cout << "Total Triangle area: " << Tri->getArea() << endl;
// Can't use CTAD as for Rect and Tri. We have to specify 'Shape'.
ptr<Shape> shape;
char userInput;
std::cin >> userInput;
if (userInput == 'R') {
shape = std::make_shared<Rectangle>();
} else if (userInput == 'T') {
shape = std::make_shared<Triangle>();
}
cout << shape->getArea() << endl;
return 0;
}
In C++ is it possible to declare an object as an abstract class, but then instantiate it to a derived class?
你不能声明一个对象,不。无法实例化抽象 classes。但是,您可以声明一个 reference/pointer 到实现抽象 class 的对象,是的。例如:
Shape *shape;
if (userInput == 'R') {
shape = new Rectangle();
} else if (userInput == 'T') {
shape = new Triangle();
}
// etc.
delete shape;
在C++11及之后的版本中,你可以使用std::unique_ptr
or std::shared_ptr
在指针超出作用域时自动为你调用delete
,eg:
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
时将调用正确的派生析构函数20=]指针:
class Shape {
public:
virtual ~Shape() {}
// ...
};
问题是抽象 class 定义的虚函数中并非 所有 都在派生的 classes 中实现。
我需要
// Derived classes
class Rectangle: public Shape {
public:
int getArea() {
return (width * height);
}
int getNumOfSides() {
return 4;
}
};
class Triangle: public Shape {
public:
int getArea() {
return (width * height)/2;
}
int getNumOfSides() {
return 3;
}
};