C ++显式实例化非模板类型

时间:2017-05-10 18:58:50

标签: c++ templates inheritance

我正在读一本关于C ++的书。我还是很公平,但我仍然在努力完成细节。这一部分涉及继承,目标是制作一个形状类,然后用第一个二维形状构建到它上面,然后用二维形状构建三维形状。

到目前为止,我已经能够一路上升并完成二维形状。那里的功能很好。我现在已经转向了三维形状,这就是我遇到一些问题的地方。

这本书说实现一个允许长度,高度和三维宽度的系统是整数或浮点数,所以我已经在其中放置了一个模板来做到这一点。这就是我认为我遇到问题的地方。

我确实将二维类复制并复制到三维类中并尝试从那里完成它。然后我把它运行到了一点问题。

当我尝试编译时,我得到两个主要错误。

错误:' ThreeD'不是类模板 错误:显式实例化非模板类型' ThreeD'

我认为是需要提交相关信息的最小部分。请记住,main.cpp,shape.h,shape.cpp,twod.h和twod.cpp可以正常工作,但我已经包含了完整的标题而不是完整的其他cpps。

你能提供的任何帮助都会很棒。

我已将ThreeD.cpp置于顶部,因为错误来自此处。

我不认为它是"为什么模板只能在头文件中实现?"因为代码适用于TwoD类,而不是ThreeD类。

ThreeD.cpp

#include <iostream>
#include <string>
#include "shape.h"
#include "TwoD.h"

using namespace std;

template class ThreeD<int>;
template class ThreeD<float>;


    template <class T>
    ThreeD<T>::ThreeD (string oobj, int osides, T olength, T oheight, T owidth)
        : TwoD<T>(oobj, osides, olength, oheight)
    {
        setObject(obj);
        setSides(sides);
        setLength(length);
        setHeight(height);
        setWidth(owidth);
    } //End of TwoD constructor

template <class T>
int ThreeD<T>::getSides() {
    return sides;
} //End of function getSides

的main.cpp

#include <iostream>
#include "shape.h"
#include "TwoD.h"
#include "ThreeD.h"

using namespace std;

int main() {


TwoD<float> triangle("Triangle", 3, 3, 3);

ThreeD<float> cube("Cube", 6, 3, 3, 3);
}

Shape.h

#ifndef SHAPE_H
#define SHAPE_H

#include <string>

using namespace std;

//Implimenting template <class T> as a means to have the sides
//variable become either a float or an int.
template <class T>
class Shape {

public:
    Shape(string, int, T);
//    void setObject(string); //Used to ensure constructor works
    virtual void setObject(string) = 0;
//Used setObject as virtual function since constructor uses it to
//Make the object using the setObject function.
    string getObject();
    int getSides();
    bool setSides(int);
    float getLength();
    void setLength (T);

    float getPerimeter(string, T);
    float getArea (string, T);

    void display();
private:
    string object;
    int sides;
    T length;
};

#endif

Shape.cpp

#include <iostream>
#include <string>
#include "shape.h"

using namespace std;

//Telling the compiler template class of Shape which versions for T to
//expect either int or float.
template class Shape<int>;
template class Shape<float>;

//Constructor of Shape. Inputs shape, sides, and length.
    template <class T>
    Shape<T>::Shape (string shapes, int sides, T length){
        setObject(shapes);
        setSides(sides);
        setLength(length);
    } //End of Shape constructor

TwoD.h

#ifndef TWOD_H
#define TWOD_H

#include <string>
#include "shape.h"

using namespace std;

//Implimenting template <class T> as a means to have the sides
//variable become either a float or an int.
template <class T>
class TwoD : public Shape<T>
{

public:
    TwoD(std::string, int, T, T);
    void setObject(string); //Used to ensure constructor works
//    virtual void setObject(string) = 0;
//Used setObject as virtual function since constructor uses it to
//Make the object using the setObject function.
    string getObject();
    int getSides();
    bool setSides(int);
    T getLength();
    void setLength (T);
    T getHeight();
    void setHeight (T);

    float getPerimeter(string, T, T);
    float getArea (string, T, T);

    void display();
private:
    string object;
    int sides;
    T length;
    T height;
};

#endif

TwoD.cpp

#include <iostream>
#include <string>
#include "shape.h"
#include "TwoD.h"

using namespace std;

//Telling the compiler template class of TwoD which versions for T to
//expect either int or float.
template class TwoD<int>;
template class TwoD<float>;

//Constructor of TwoD. Inputs TwoD, sides, and length.
    template <class T>
    TwoD<T>::TwoD (string obj, int sides, T length, T height)
        : Shape<T>(obj, sides, length)
    {
        setObject(obj);
        setSides(sides);
        setLength(length);
        setHeight(height);
    } //End of TwoD constructor

ThreeD.h

#ifndef THREED_H
#define THREED_H

#include <string>
#include "shape.h"
#include "TwoD.h"

using namespace std;

//Implimenting template <class T> as a means to have the sides
//variable become either a float or an int.
template <class T>
class ThreeD : public TwoD<T>
{

public:
    ThreeD(std::string, int, T, T, T);
    void setObject(std::string); //Used to ensure constructor works
//    virtual void setObject(string) = 0;
//Used setObject as virtual function since constructor uses it to
//Make the object using the setObject function.
    string getObject();
    int getSides();
    bool setSides(int);
    T getLength();
    void setLength (T);
    T getHeight();
    void setHeight (T);

    T getWidth();
    void setWidth (T);

    float getPerimeter(string, T, T, T);
    float getArea (string, T, T, T);

    void display();
private:
    std::string object;
    int sides;
    T length;
    T height;
    T width;
};

#endif

1 个答案:

答案 0 :(得分:1)

ThreeD.cpp中你需要:

#include "ThreeD.h"

没有它,行template class ThreeD<int>;对编译器没有意义,因为ThreeD尚未声明。