【发布时间】:2020-02-03 20:04:33
【问题描述】:
对于 3 向量类
template <typename T>
class vec3 {
template <typename U>
friend std::ostream& operator<<(std::ostream& out, const vec3<U>& v);
template <typename U>
friend std::istream& operator>>(std::istream& in, vec3<U>& v);
protected:
std::vector<T> data;
public:
vec3 ( ): data(3)
{}; // default constructor
vec3 ( T x, T y, T z ): data(3)
{ data[0] = x; data[1] = y; data[2] = z; } // constructor from 3 scalars
vec3 ( T* xyz ): data(3)
{ std::copy (xyz, xyz+3, data.begin() ); } // constructor from pointer
vec3 ( const vec3<T>& rhs ): data(3)
{ std::copy ( rhs.data.begin(), rhs.data.end(), data.begin() ); } // copy constructor
vec3<T> operator=( vec3<T> rhs ) {
std::copy( rhs.data.begin(), rhs.data.end(), data.begin() ); // assignment
return (*this);
}
// passing on the [] operator for accessing elements
T& operator[] ( size_t offset)
{ return data[offset]; } // write access
const T& operator[] ( size_t offset) const
{ return data[offset]; } // read access
// left += and + for elements and vectors
template <typename U>
const vec3<T>& operator+= ( const U& rhs )
{ data[0]+=rhs; data[1]+=rhs; data[2]+=rhs; return (*this); }
template <typename U>
const vec3<T>& operator+= ( const vec3<U>& rhs )
{ data[0]+=rhs[0]; data[1]+=rhs[1]; data[2]+=rhs[2]; return (*this); }
template <typename U>
const vec3<T> operator+ ( const U& rhs )
{ vec3<T> out(*this); out += rhs; return out; }
// left *= and * for elements and vectors
template <typename U>
const vec3<T>& operator*= ( const U& rhs )
{ data[0]*=rhs; data[1]*=rhs; data[2]*=rhs; return (*this); }
template <typename U>
const vec3<T>& operator*= ( const vec3<U>& rhs )
{ data[0]*=rhs[0]; data[1]*=rhs[1]; data[2]*=rhs[2]; return (*this); }
template <typename U>
const vec3<T> operator* ( const U& rhs )
{ vec3<T> out(*this); out *= rhs; return out; }
// rest of the operators
}
template <typename U>
std::ostream& operator<<(std::ostream& out, const vec3<U>& v)
{ return out << '(' << v.data[0] << ',' << v.data[1] << ',' << v.data[2] <<')'; }
template <typename U>
std::istream& operator>>(std::istream& in , vec3<U> &v)
{ return in >> v.data[0] >> v.data[1] >> v.data[2]; }
我尝试运行这段代码
float v[3] = { 10, 20, 30 };
vec3<float> v1 (v);
std::cout << v1 << " \n";
vec3<float> v2 (v1);
std::cout << v2 << " \n";
vec3<float> v3 = v2;
std::cout << v3 << " \n \n";
v3+=1.;
std::cout << v3 << " \n";
v3=v1+v2*2;
std::cout << v3 << " \n";
返回
(10,20,30)
(10,20,30)
(10,20,30)
(11,21,31)
Segmentation fault
所以我对复制构造函数、赋值等有足够的信心,但是不可能将* 操作的结果传递给+ 吗?它返回一个const vec3<T> 那么这里出了什么问题?我猜是一些菜鸟的错误,但我没有看到。
【问题讨论】:
-
通常,您会希望从
+=和*=运算符返回T&而不是const T&。你应该花点时间阅读What are the basic rules and idioms for operator overloading?。 -
问题很可能出在您的 ctors 或作业中——您应该向他们展示(以及您的成员 vars)
-
如果你的返回类型不是引用也不是指针,那么它不应该是
const。在这些情况下,返回值const不会提供任何东西,而是禁用移动语义和优化。 -
另外,为什么要对 3 个元素使用动态分配?为此目的,有
std::array。 -
:/ Godbolt 使用 gcc9.2。您将哪些选项传递给 gcc?您可以将代码发布到在线编译器并重现问题吗?我记得 CodeBlocks 有一个简单易用的调试器前端。
标签: c++ segmentation-fault operators pass-by-reference pass-by-value