简体   繁体   English

工厂设计模式中的纯虚函数错误

[英]Pure Virtual Function error in factory design pattern

studying for a final and decided to build a program which makes use of pure virtual functions and polymorphism. 经过研究,最终决定构建一个利用纯虚函数和多态性的程序。 i am stuck on a really weird error maybe i am missing something. 我陷入了一个非常奇怪的错误,也许我错过了一些东西。

This is the Shape abstract class 这是Shape抽象类

#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 */

The Shape .cpp implementation file Shape .cpp实现文件

#include "Shape.hpp"

Shape::Shape(const char *shape){
    name = shape;
}

The Circle Header file 圆头文件

#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 */

The circle .cpp implementation file 圆.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;
}

I declared the two pure virtual functions in the abstract "shape" class and am accessing the public of shape class in circle header file, if i declare the pure virtual functions in the circle class it will make it abstract... the error says "Out-of-line definition of 'getPerimeter' does not match any declaration in 'Circle'" 我在抽象的“ shape”类中声明了这两个纯虚函数,并且正在访问圆形头文件中的shape类的公共对象,如果我在circle类中声明了纯虚函数,它将使其抽象化。 “ getPerimeter”的脱机定义与“ Circle”中的任何声明都不匹配”

Am i missing something or am i thinking about this the wrong way.. 我是否想念某些东西,还是我在想这个错误的方法..

Help would be appreciated. 帮助将不胜感激。 Thanks! 谢谢!

You need to declare all member functions that you define. 您需要声明您定义的所有成员函数。 So in class Circle you need to add: 因此,在class Circle您需要添加:

virtual double getPerimeter();

Or better in C++11: 或者在C ++ 11中更好:

double getPerimeter() override;

You're defining Circle::getPerimeter() in your .cpp file but there is no member function getPerimeter() in the Circle class declaration. 您正在.cpp文件中定义Circle::getPerimeter() ,但是Circle类声明中没有成员函数getPerimeter()。 All pure virtual functions need to be overriden in a derived class in order for the class to become concrete. 为了使该类变得具体,需要在派生类中重写所有纯虚函数。 So yes, virtual double getPerimeter(); 是的, virtual double getPerimeter(); and override if you're using C++11. 并在使用C ++ 11时override

Also, it's good practice to declare simple getters const . 另外,优良作法是声明简单的getters const

It should be done this way. 应该以这种方式完成。

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
};

Here's a suggestion. 这是一个建议。 Since Shape is an abstract class, we cannot create objects of the class; 由于Shape是一个抽象类,因此我们无法创建该类的对象。 so get rid of its constructor. 所以摆脱它的构造函数。 Since we are interested in area and parameter of shapes, define the functions as virtual. 由于我们对形状的面积和参数感兴趣,因此将函数定义为虚函数。

So, here is a redeclaration of Shape class. 因此,这里是Shape类的重新声明。

#ifndef __SHAPE__
#define __SHAPE__
namespace shape
{
    class Shape
    {
        public:
            virtual float getArea()=0;
            virtual float getPerimeter()=0;
    };
}
#endif

Now, redeclaration of Circle class 现在,重新声明Circle类

#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

Now redefining Circle class 现在重新定义Circle类

#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);
    }
}

Now, in the main 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;
}

You may redeclare the classes without namespaces. 您可以重新声明不带名称空间的类。

The point to note is that the type of object created should be of the parent class and the object itself should be a child class. 需要注意的一点是,创建的对象类型应该是父类,而对象本身应该是子类。

One last thing; 最后一件事; all pure virtual functions in the abstract must be redeclared and redefined (overridden) in the derived classes. 必须在派生类中重新声明和重新定义(重写)摘要中的所有纯虚函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM