工厂设计模式中的纯虚函数错误
Pure Virtual Function error in factory design pattern
正在学习期末考试并决定构建一个利用纯虚函数和多态性的程序。我遇到了一个非常奇怪的错误,也许我遗漏了什么。
这是形状摘要class
#ifndef Shape_hpp
#define Shape_hpp
#include <stdio.h>
#include <string.h>
class Shape{
const char* name;
public:
Shape(const char* abc);
virtual double getPerimeter()=0;
virtual double getArea()=0;
};
#endif /* Shape_hpp */
Shape .cpp 实现文件
#include "Shape.hpp"
Shape::Shape(const char *shape){
name = shape;
}
Circle 头文件
#ifndef Circle_hpp
#define Circle_hpp
#include "Shape.hpp"
#include <stdio.h>
class Circle:public Shape{
double m_radius;
public:
Circle(double rad);
double getRadius();
};
#endif /* Circle_hpp */
圈.cpp实现文件
#include "Circle.hpp"
#include "Shape.hpp"
Circle::Circle(double rad):Shape("Circle"){
m_radius = rad;
}
double Circle::getRadius(){
return m_radius;
}
double Circle::getPerimeter(){
return (2 * 3.14 * m_radius);
}
double getArea(){
return 0;
}
我在抽象 "shape" class 中声明了两个纯虚函数,并且正在访问圆形头文件中形状 class 的 public,如果我声明圆圈中的纯虚函数 class 它将使其变得抽象...错误显示 "Out-of-line definition of 'getPerimeter' does not match any declaration in 'Circle'"
我是不是遗漏了什么或者我是不是想错了..
帮助将不胜感激。谢谢!
您需要声明您定义的所有成员函数。所以在 class Circle
你需要添加:
virtual double getPerimeter();
或在 C++11 中更好:
double getPerimeter() override;
您在 .cpp 文件中定义了 Circle::getPerimeter()
,但 Circle class 声明中没有成员函数 getPerimeter()。为了使 class 变得具体,所有纯虚函数都需要在派生的 class 中被覆盖。所以是的,virtual double getPerimeter();
和 override
如果您使用的是 C++11。
另外,声明简单的 getters 是个好习惯 const
。
这是一个建议。由于 Shape 是抽象的 class,我们无法创建 class 的 object;所以摆脱它的构造函数。由于我们对形状的面积和参数感兴趣,因此将函数定义为虚函数。
所以,这里是 Shape class 的重新声明。
#ifndef __SHAPE__
#define __SHAPE__
namespace shape
{
class Shape
{
public:
virtual float getArea()=0;
virtual float getPerimeter()=0;
};
}
#endif
现在,重新声明 Circle class
#ifndef __CIRCLE__
#define __CIRCLE__
#include "inc/Shape.hpp"
namespace shape
{
class Circle: public Shape
{
float radius;
public:
Circle(float=0.0);
float getArea();
float getPerimeter();
};
}
#endif
现在重新定义圆class
#include "inc/Circle.hpp"
namespace shape
{
Circle::Circle(float radius)
{
this->radius = radius;
}
float Circle::getArea()
{
return ((22/7) * (this->radius * this->radius));
}
float Circle::getPerimeter()
{
return (2 * (22/7) * this->radius);
}
}
现在主要是class
#include <iostream>
#include "inc/Circle.hpp"
int main()
{
shape::Shape *circle = new shape::Circle(2.5);
std::cout << "Area: " << circle->getArea() << std::endl;
std::cout << "Perimeter: " << circle->getPerimeter() << std::endl;
return 0;
}
您可以重新声明没有命名空间的 classes。
需要注意的是,创建的object的类型应该是parentclass和object本身应该是一个childclass。
最后一件事;抽象中的所有纯虚函数必须在派生的 classes.
中重新声明和重新定义(覆盖)
应该这样做。
class Shape{
const char* name;
public:
Shape(const char* abc);
virtual ~Shape() {} // you should have virtual destructor here
virtual double getPerimeter()=0;
virtual double getArea()=0;
};
class Circle:public Shape{
double m_radius;
public:
Circle(double rad);
double getRadius();
virtual double getPerimeter(); // we need to re-declare it here
virtual double getArea(); // we need to re-declare it here
};
正在学习期末考试并决定构建一个利用纯虚函数和多态性的程序。我遇到了一个非常奇怪的错误,也许我遗漏了什么。
这是形状摘要class
#ifndef Shape_hpp
#define Shape_hpp
#include <stdio.h>
#include <string.h>
class Shape{
const char* name;
public:
Shape(const char* abc);
virtual double getPerimeter()=0;
virtual double getArea()=0;
};
#endif /* Shape_hpp */
Shape .cpp 实现文件
#include "Shape.hpp"
Shape::Shape(const char *shape){
name = shape;
}
Circle 头文件
#ifndef Circle_hpp
#define Circle_hpp
#include "Shape.hpp"
#include <stdio.h>
class Circle:public Shape{
double m_radius;
public:
Circle(double rad);
double getRadius();
};
#endif /* Circle_hpp */
圈.cpp实现文件
#include "Circle.hpp"
#include "Shape.hpp"
Circle::Circle(double rad):Shape("Circle"){
m_radius = rad;
}
double Circle::getRadius(){
return m_radius;
}
double Circle::getPerimeter(){
return (2 * 3.14 * m_radius);
}
double getArea(){
return 0;
}
我在抽象 "shape" class 中声明了两个纯虚函数,并且正在访问圆形头文件中形状 class 的 public,如果我声明圆圈中的纯虚函数 class 它将使其变得抽象...错误显示 "Out-of-line definition of 'getPerimeter' does not match any declaration in 'Circle'"
我是不是遗漏了什么或者我是不是想错了..
帮助将不胜感激。谢谢!
您需要声明您定义的所有成员函数。所以在 class Circle
你需要添加:
virtual double getPerimeter();
或在 C++11 中更好:
double getPerimeter() override;
您在 .cpp 文件中定义了 Circle::getPerimeter()
,但 Circle class 声明中没有成员函数 getPerimeter()。为了使 class 变得具体,所有纯虚函数都需要在派生的 class 中被覆盖。所以是的,virtual double getPerimeter();
和 override
如果您使用的是 C++11。
另外,声明简单的 getters 是个好习惯 const
。
这是一个建议。由于 Shape 是抽象的 class,我们无法创建 class 的 object;所以摆脱它的构造函数。由于我们对形状的面积和参数感兴趣,因此将函数定义为虚函数。
所以,这里是 Shape class 的重新声明。
#ifndef __SHAPE__
#define __SHAPE__
namespace shape
{
class Shape
{
public:
virtual float getArea()=0;
virtual float getPerimeter()=0;
};
}
#endif
现在,重新声明 Circle class
#ifndef __CIRCLE__
#define __CIRCLE__
#include "inc/Shape.hpp"
namespace shape
{
class Circle: public Shape
{
float radius;
public:
Circle(float=0.0);
float getArea();
float getPerimeter();
};
}
#endif
现在重新定义圆class
#include "inc/Circle.hpp"
namespace shape
{
Circle::Circle(float radius)
{
this->radius = radius;
}
float Circle::getArea()
{
return ((22/7) * (this->radius * this->radius));
}
float Circle::getPerimeter()
{
return (2 * (22/7) * this->radius);
}
}
现在主要是class
#include <iostream>
#include "inc/Circle.hpp"
int main()
{
shape::Shape *circle = new shape::Circle(2.5);
std::cout << "Area: " << circle->getArea() << std::endl;
std::cout << "Perimeter: " << circle->getPerimeter() << std::endl;
return 0;
}
您可以重新声明没有命名空间的 classes。
需要注意的是,创建的object的类型应该是parentclass和object本身应该是一个childclass。
最后一件事;抽象中的所有纯虚函数必须在派生的 classes.
中重新声明和重新定义(覆盖)应该这样做。
class Shape{
const char* name;
public:
Shape(const char* abc);
virtual ~Shape() {} // you should have virtual destructor here
virtual double getPerimeter()=0;
virtual double getArea()=0;
};
class Circle:public Shape{
double m_radius;
public:
Circle(double rad);
double getRadius();
virtual double getPerimeter(); // we need to re-declare it here
virtual double getArea(); // we need to re-declare it here
};