很难让标题非常清楚,但我会尝试解释上下文(下面有一些代码)。注意:我已经看到类似的问题得到了解答,但他们只用1个孩子类来处理这些案例。所以他们在我的案例中并没有真正帮助,因为我有2个孩子班。
上下文 我有一个父类Shape有两个孩子:圆形和方形。 我将有一个Shape对象的矢量,但这些Shape对象实际上只是Circle对象或Square对象。我需要Circle和Square类具有相同的父类,以便我可以将它们存储在同一个向量中。
诀窍是我需要使用向量中的Shape对象来调用Circle类或Square类中实现的方法,因此,我需要在父类中拥有这些方法的“虚拟”版本形状
以下是我的课程代码的简化部分:
Shape.h:
class Shape{
public:
std::string getColor();
virtual int getRadius() = 0; //Method implemented in Circle
virtual int getHeight() = 0; //Method implemented in Square
virtual int getWidth() = 0; //Method implemented in Square
protected:
std::string color;
};
class Circle : public Shape{
public:
int getRadius();
private:
int radius;
};
class Square : public Shape{
public:
int getHeight();
int getWidth();
private:
int height;
int width;
};
在Shape.cpp中,我有类似的东西:
std::string Shape::getColor(){
return color;
}
int Circle::getRadius(){
return radius;
}
int Square::getHeight(){
return height;
}
int Square::getWidth(){
return width;
}
当我想要创建Circle和Square对象时,main.cpp中会出现错误:
Circle *c = new Circle(...);//Error: cannot instantiate abstract class
//pure virtual function "Shape::getHeight" has no overrider
//pure virtual function "Shape::getWidth" has no overrider
Square *s = new Square(...);//Error: cannot instantiate abstract class
//pure virtual function "Shape::getRadius" has no overrider
所以我似乎需要在Square类中声明“getRadius”并在Circle类中声明“getHeight”和“getWidth”...
我尝试用虚拟添加它们,但这使得Circle和Square抽象类,所以我不能用它们创建任何对象。
有没有办法让这项工作?
这是我在stackoverflow上发布的第一个问题。我希望一切都清楚。谢谢你的帮助!
答案 0 :(得分:2)
您的虚拟方法不适合虚拟方法,因为它们具有一个类的特定功能,但对另一个类没有用。
虚拟方法的好例子是每个类实现但具有不同功能或结果的东西,如virtual int area()
或virtual bool intersects( Shape * otherShape )
等等。
无论如何,这就是你如何编译你的代码(带一些额外的东西):
形状:
class Shape{
public:
std::string getColor();
Shape() {}
virtual ~Shape() {}
virtual int getRadius() { return 0; } // no pure virtual
virtual int getHeight() { return 0; } // no pure virtual
virtual int getWidth() { return 0; } // no pure virtual
protected:
std::string color;
};
class Circle : public Shape {
public:
Circle( int r )
: Shape()
, radius( r )
{}
Circle() : Circle( 0 ) {}
~Circle() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
int getRadius() override { return radius; };
private:
int radius;
};
正方形:
class Square : public Shape {
public:
Square( int h, int w )
: Shape()
, height( h )
, width( w )
{}
Square() : Square( 0, 0 ) {}
~Square() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
int getHeight() override { return height; }
int getWidth() override { return width; }
private:
int height;
int width;
};
测试:
int main() {
using shapes = std::vector< Shape * >;
shapes s;
s.push_back( new Circle( 10 ) );
s.push_back( new Square() );
s.push_back( new Square( 1, 3 ) );
s.push_back( new Circle() );
for ( Shape * sh : s ) {
std::cout
<< " r " << sh->getRadius()
<< " h " << sh->getHeight()
<< " w " << sh->getWidth()
<< std::endl;
}
for ( Shape * sh : s ) { delete sh; } s.clear();
}
输出:
r 10 h 0 w 0
r 0 h 0 w 0
r 0 h 1 w 3
r 0 h 0 w 0
virtual Circle::~Circle()
virtual Square::~Square()
virtual Square::~Square()
virtual Circle::~Circle()
以下是使用区域示例的虚拟方法的更好用法:
#include <iostream>
#include <vector>
struct Shape {
Shape() {}
virtual ~Shape() {}
virtual double area() = 0;
};
以不同的区域实施扩展:
struct Circle : public Shape {
Circle( int r )
: Shape()
, radius( r )
{}
Circle() : Circle( 0 ) {}
~Circle() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
virtual double area() override { return radius * radius * 3.14; }
int radius;
};
struct Square : public Shape {
Square( int h, int w )
: Shape()
, height( h )
, width( w )
{}
Square() : Square( 0, 0 ) {}
~Square() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
virtual double area() override { return height * width; }
int height;
int width;
};
测试
int main() {
using shapes = std::vector< Shape * >;
shapes s;
s.push_back( new Circle( 1 ) );
s.push_back( new Square( 1, 1 ) );
s.push_back( new Square( 2, 3 ) );
s.push_back( new Circle( 2 ) );
for ( Shape * sh : s ) {
std::cout << sh->area() << std::endl;
}
for ( Shape * sh : s ) { delete sh; } s.clear();
}
输出:
3.14
1
6
12.56
virtual Circle::~Circle()
virtual Square::~Square()
virtual Square::~Square()
virtual Circle::~Circle()
答案 1 :(得分:0)
我希望您了解pure virtual
和virtual
函数之间的区别。 Pure virtual
函数基本上是占位符函数,其中包含否正文。您的基类形状更适合普通virtual
函数,这些函数可以但不必在子类中更改。取出函数声明中的= 0
部分,使函数只是普通的virtual
函数。
答案 2 :(得分:0)
这应该让你朝着正确的方向前进。通过使您的成员不是纯虚拟,您可以在派生类中实现它们,但您不需要。
class Shape{
public:
std::string getColor();
virtual int getRadius(); //Method implemented in Circle
virtual int getHeight(); //Method implemented in Square
virtual int getWidth(); //Method implemented in Square
protected:
std::string color;
};
class Circle : public Shape{
public:
int getRadius();
private:
int radius;
};
class Square : public Shape{
public:
int getHeight();
int getWidth();
private:
int height;
int width;
};