如下所示我想要在类外重载“<<”但会报错无法解析符号(我在main函数中cout了这个类的实例),如果不在main函数中cout它就正常运行,如果我在类中直接定义也会成功运行,那么正确的声明应该怎样写?
#pragma once
#include <iostream>
// 使用模板定义三维类
template<class T>
class Vector3
{
public:
// 顶点或向量的其次坐标
T x, y, z, w;
// 构造函数
Vector3();
Vector3(T x, T y, T z);
Vector3(T x, T y, T z, T w);
// 三维+三维=三维
Vector3<T> operator + (const Vector3<T>& right)const;
// 三维-三维=三维
Vector3<T> operator - (const Vector3<T>& right)const;
// 三维*常数=三维
Vector3<T> operator * (float value)const;
// 三维/常数=三维
Vector3<T> operator / (float value)const;
// 计算向量的平方
float SquareMagnitude();
// 计算向量的长度(即平方根)
float Magnitude();
// 标准化向量
Vector3<T>& Normalize();
// 向量的点乘
static float Dot(const Vector3<T>& left, const Vector3<T>& right);
// 向量的点乘
float Dot(const Vector3<T>& right);
// 向量的叉积
Vector3<T> Cross(const Vector3<T>& left, const Vector3<T>& right);
friend std::ostream& operator << (std::ostream& out, const Vector3<T> s);
};
template<class T>
std::ostream& operator << (std::ostream& out, const Vector3<T> s)
{
out << "[" << s.x << "," << s.y << "," << s.z << "]" << std::endl;
return out;
}
template<class T>
Vector3<T>::Vector3()
{
x = y = z = 0;
w = 1;
}
template<class T>
Vector3<T>::Vector3(T x, T y, T z)
{
this->x = x;
this->y = y;
this->z = z;
this->w = 1;// 不传入w默认为三维顶点
}
template<class T>
Vector3<T>::Vector3(T x, T y, T z, T w)
{
this->x = x;
this->y = y;
this->z = z;
this->w = w;
}
// 三维+三维=三维
template<class T>
Vector3<T> Vector3<T>::operator + (const Vector3<T>& right)const
{
Vector3<T> res = Vector3<T>(x + right.x, y + right.y, z + right.z);
return res;
}
// 三维-三维=三维
template<class T>
Vector3<T> Vector3<T>::operator - (const Vector3<T>& right)const
{
Vector3<T> res = Vector3<T>(x - right.x, y - right.y, z - right.z);
return res;
}
// 三维*常数=三维
template<class T>
Vector3<T> Vector3<T>::operator * (float value)const
{
Vector3<T> res = Vector3<T>(x * value, y * value, z * value);
return res;
}
// 三维/常数=三维
template<class T>
Vector3<T> Vector3<T>::operator / (float value)const
{
Vector3<T> res = Vector3<T>(x / value, y / value, z / value);
return res;
}
// 计算向量的平方
template<class T>
float Vector3<T>::SquareMagnitude()
{
return Dot(*this, *this);
}
// 计算向量的长度(即平方根)
template<class T>
float Vector3<T>::Magnitude()
{
return sqrt(SquareMagnitude());
}
// 标准化向量
template<class T>
Vector3<T>& Vector3<T>::Normalize()
{
*this = *this / Magnitude();
return *this;
}
// 向量的点乘
template<class T>
static float Vector3<T>::Dot(const Vector3<T>& left, const Vector3<T>& right)
{
return left.x * right.x + left.y * right.y + left.z * right.z;
}
// 向量的点乘
template<class T>
float Vector3<T>::Dot(const Vector3<T>& right)
{
return x * right.x + y * right.y + z * right.z;
}
// 向量的叉积
template<class T>
Vector3<T> Vector3<T>::Cross(const Vector3<T>& left, const Vector3<T>& right) {
float valueX = left.y * right.z - left.z * right.y;
float valueY = left.z * right.x - left.x * right.z;
float valueZ = left.x * right.y - left.y * right.x;
Vector3<T> returnValue(valueX, valueY, valueZ);
return returnValue;
}
友元函数的形式,需要额外提供一个操作数:
加个 inline 在 实现的地方?