[英]Friend template function in C++
目前在C ++上使用模板进行一些练习,在重载它们时使用好友函数时,我遇到了一些麻烦。 我在ofstream和istream中都得到了臭名昭著的无法解决的外部符号错误。 对此的任何帮助将不胜感激。
.H文件
#pragma once
#include "TriangleInterface.h"
template <class type>
class Triangle : public TriangleInterface<type> {
private:
const int SIZE = 3;
type height;
type base;
type length;
vector<type> angles;
public:
Triangle();
Triangle(type aHeight, type aLength, type aBase, type firstAngle, type secondAngle, type thirdAngle);
~Triangle();
void setHeight(type aHeight);
void setBase(type aBase);
void setLength(type aLength);
void setAngles(vector<type> &theAngles);
type getHeight();
type getBase();
type getLength();
type getArea();
void determineType();
friend ostream & operator << <>(ostream &out, const Triangle &aTriangle);
friend istream &operator >> <>(istream &in, Triangle &aTriangle);
};
.cpp文件
#include "Triangle.h"
using namespace std;
template<class type>
Triangle<type>::Triangle() {
height = 0;
length = 0;
base = 0;
angles.assign(60);
}
template<class type>
Triangle<type>::Triangle(type aHeight, type aLength, type aBase, type firstAngle, type secondAngle, type thirdAngle) {
angles.push_back(firstAngle);
angles.push_back(secondAngle);
angles.push_back(thirdAngle);
height = aHeight;
length = aLength;
base = aBase;
}
template<class type>
Triangle<type>::~Triangle() {};
template <class type>
void Triangle<type>::setBase(type aBase) {
this->base = aBase;
}
template <class type>
void Triangle<type>::setHeight(type aHeight) {
this->height = aHeight;
}
template <class type>
void Triangle<type>::setLength(type aLength) {
this->length = aLength;
}
template <class type>
void Triangle<type>::setAngles(vector<type> &theAngles) {
this->angles = theAngles;
}
template<class type>
type Triangle<type>::getBase() {
return this->base;
}
template<class type>
type Triangle<type>::getHeight() {
return this->height;
}
template<class type>
type Triangle<type>::getLength() {
return this->length;
}
template <class type>
type Triangle<type>::getArea() {
return (this->(base * height) / 2);
}
template<class type>
void Triangle<type>::determineType() {
if (base == length && length == height && angles[0] == angles[1] && angles[1] == angles[2])
cout << "This is an equilateral triangle.\n";
else if (base == length || base == height || length == height && angles[0] == angles[1] || angles[1] == angles[2] || angles[0] == angles[2])
cout << "This is an Isosceles Triangle.\n";
else
cout << "This is a Scalene Triangle.\n";
}
template<class type>
ostream &operator << (ostream &out, const Triangle<type> &aTriangle) {
out << endl;
out << "The height of your triangle is " << aTriangle.getHeight() << endl;
out << "The base of your triangle is " << aTriangle.getBase() << endl;
out << "The length of your triangle is " << aTriangle.getLength() << endl;
out << endl;
out << "The Area of your triangle is " << aTriangle.getArea() << endl;
out << aTriangle.determineType() << endl;
for (int i = 0; i < SIZE; i++) {
out << "Angle #" << i << " : " << angles[i] << endl;
}
return out;
}
template<class type>
istream &operator >> (istream &in, Triangle<type> &aTriangle) {
cout << "Enter the height: ";
in >> aTriangle.height;
cout << "Enter the length: ";
in >> aTriangle.length;
cout << "Enter the base: ";
in >> aTriangle.base;
cout << "Enter the angles: " << endl;
for (int i = 0; i < SIZE; i++) {
cout << "Angle #" << i << " : ";
in >> angles[i];
}
return in;
}
错误:
Error 5 error LNK1120: 4 unresolved externals C:\Users\Silvestrini\Dropbox\CECS 3212\Week 3\HomeWork\Week 3\Debug\Triangle ADT.exe 1 1 Triangle ADT
Error 4 error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl std::>>(class std::basic_istream<char,struct std::char_traits<char> > &,class Triangle<double> &)" (?>>@std@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@1@AAV21@AAV?$Triangle@N@@@Z) referenced in function _main C:\Users\Silvestrini\Dropbox\CECS 3212\Week 3\HomeWork\Week 3\Triangle ADT\driver.obj Triangle ADT
Error 3 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Triangle<double> const &)" (?<<@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@ABV?$Triangle@N@@@Z) referenced in function _main C:\Users\Silvestrini\Dropbox\CECS 3212\Week 3\HomeWork\Week 3\Triangle ADT\driver.obj Triangle ADT
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Triangle<double>::~Triangle<double>(void)" (??1?$Triangle@N@@QAE@XZ) referenced in function _main C:\Users\Silvestrini\Dropbox\CECS 3212\Week 3\HomeWork\Week 3\Triangle ADT\driver.obj Triangle ADT
Error 1 error LNK2019: unresolved external symbol "public: __thiscall Triangle<double>::Triangle<double>(void)" (??0?$Triangle@N@@QAE@XZ) referenced in function _main C:\Users\Silvestrini\Dropbox\CECS 3212\Week 3\HomeWork\Week 3\Triangle ADT\driver.obj Triangle ADT
对于大多数编译器,默认情况下,模板的定义必须在声明模板的头文件中。 这是因为编译器需要在实例化模板的每个编译单元中完全了解模板定义。
简而言之,请将您的.cpp文件的内容添加到.h文件的末尾,并将.cpp文件从构建中排除(请勿编译该文件,或链接到相应的目标文件中)。
注意:取决于您的编译器,有一些替代方法,但是,如果您无法按照我所描述的方式使代码正常工作,那么使用这些替代方法将更加困难。
您显示的任何代码中都没有#include <iostream>
,这无济于事。 该标头对于std::istream
和std::ostream
类型是必需的。
绝对不要using namespace std;
在头文件中(这意味着与模板声明有关的任何内容),因为在某些情况下,这样做会导致难以解决的歧义-请使用std::istream
和std::ostream
全名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.