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

时间:2015-12-15 05:55:14

标签: c++ inheritance polymorphism abstract-class pure-virtual

学习决赛并决定构建一个利用纯虚函数和多态的程序。我被困在一个非常奇怪的错误上,也许我错过了一些东西。

这是Shape抽象类

#include "Shape.hpp"

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

Shape .cpp实现文件

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

Circle Header文件

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

圆圈.cpp实施文件

  var values = [];

  $('[id^="chk"]:checked:not("#chkAll"):not("[id^="chkParent"]")').each(function() {
    values.push($(this).val());
  });

  alert(values.join());

我在抽象&#34;形状&#34;中声明了两个纯虚函数。类和我正在圆形头文件中访问shape类的公共,如果我在circle类中声明纯虚函数它会使它抽象...错误说&#34;&#34;&#39;的外线定义; getPerimeter&#39;不符合&#39; Circle&#39;&#34;

中的任何声明

我错过了什么,或者我是否以错误的方式思考......

帮助将不胜感激。谢谢!

4 个答案:

答案 0 :(得分:3)

您需要声明您定义的所有成员函数。所以在class Circle中你需要添加:

virtual double getPerimeter();

或者更好的C ++ 11:

double getPerimeter() override;

答案 1 :(得分:1)

您在.cpp文件中定义了Circle::getPerimeter(),但Circle类声明中没有成员函数getPerimeter()。所有纯虚函数都需要在派生类中重写,以使类变得具体。是的,virtual double getPerimeter();override如果你正在使用C ++ 11。

此外,宣布简单的getter const是一种很好的做法。

答案 2 :(得分:1)

应该这样做。

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

答案 3 :(得分:0)

这是一个建议。由于Shape是一个抽象类,我们不能创建类的对象;所以摆脱它的构造函数。由于我们对形状的面积和参数感兴趣,因此将函数定义为虚拟。

所以,这是Shape类的重新声明。

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

现在,重新声明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

现在重新定义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);
    }
}

现在,在主类

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

您可以重新声明没有名称空间的类。

需要注意的是,创建的对象的类型应该是父类,而对象本身应该是子类。

最后一件事;必须在派生类中重新声明并重新定义(重写)抽象中的所有纯虚函数。