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

C++ explicit instantiation of non-template type

本文关键字:实例化 类型 C++      更新时间:2023-10-16

我正在读一本关于C++的书。我仍然公平地接受它,但我仍然试图完成细节。本节涉及继承,目标是创建一个形状类,然后使用第一个二维形状构建该类,然后基于二维形状构建三维形状。

到目前为止,我已经能够一路向上并完成二维形状。那里的功能工作正常。我现在已经转向三维形状,这就是我遇到一点问题的地方。

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

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

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

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

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

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

我把ThreeD.cpp放在顶部,因为这是错误的来源。

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

三D.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

主.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);
}

形状.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

形状.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

二D.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

二D.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

三日韩

#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

ThreeD.cpp中,您需要:

#include "ThreeD.h"

否则,行template class ThreeD<int>;对编译器毫无意义,因为尚未声明ThreeD