C++运算符重载和继承
C++ Operator Overloading and Inheritance
我将从代码开始,因为它对我来说更容易解释。
vector.cpp
template <typename T, unsinged int D>
class Vector
{
public:
Vector() {}
inline Vector<T, D> operator+(const Vector<T,D>& r)
{
Vector<T,D> result = T(0);
for(int i = 0; i < D; i++)
result[i] = (*this)[i] + r[i];
return result;
}
private:
T values[D];
}
template <typename T>
class Vector3 : public Vector<T, 3>
{
// Initialization constructor etc..
}
main.cpp
int main(int argc, char** args)
{
Vector3<float> vec1 = Vector3<float>(1.0f, 2.0f, 3.0f);
Vector3<float> vec2 = Vector3<float>(1.0f, 2.0f, 3.0f);
Vector3<float> res;
res = vec1 + vec2; // Here's the error
return 1;
}
由于某种原因,我在指示的行中得到一个错误,说没有运算符"="与这些操作数匹配,操作数类型为Vector3<float> = Vector<float, 3U>
。如果我将变量"res"声明为Vector<float, 3> res;
,它就起作用了。考虑到它继承了类"Vector"的定义,我不明白为什么会发生这种情况。有人能帮我吗?我最好能让这项工作顺利进行,而不必为所有派生类重新编写运算符重载函数。我对矩阵也有类似的实现。
提前谢谢。
干杯。
此vec1 + vec2
调用父类的operator+
,后者返回父类类型的对象。不能将Vector<float, 3U>
的对象分配给Vector3<float>
类型的对象。
int main(int argc, char** args)
{
Vector<float, 3U> v;
Vector3<float> res;
res = v; // Here's the error
}
你可以做:
int main(int argc, char** args)
{
Vector3<float> vec1 = Vector3<float>(1.0f, 2.0f, 3.0f);
Vector3<float> vec2 = Vector3<float>(1.0f, 2.0f, 3.0f);
Vector<float, 3U> res = vec1 + vec2;
}
我想说,尝试使用继承可能不是最好的主意。如果你可以使用C++11,那么键入别名可能会更好:
template <typename T, unsinged int D>
class Vector
{
template<typename... Args> Vector(Args &&...args)
: values{std::forward<Args>(args)...}
{}
// ...
};
template<typename T>
using Vector3 = Vector<T, 3>;
我已重载'[]'、'==='和'!='它似乎工作没有问题,
问题是,对于operator+
,您将返回父类型Vector<float,3U>
,然后尝试在需要子类型Vector3<float>
的地方使用该类型。
使用operator[]
,您可能会返回T&
,然后在需要T&
的地方使用它。对于operator!=
和operator==
,您将返回bool
,并在需要bool
的地方使用它。你看到区别了吗?你明白为什么吗:
Vector3<float> res = Vector3<float>();
作品和
Vector3<float> res = Vector<float, 3U>();
不是吗?
请您进一步解释别名是什么类型,以及它如何改进上述实现,以及为什么会这样做。
你可以在很多地方读到它们是什么。它们对您的使用来说很重要的一点是,它们并没有创建新的类型,只是创建了一种引用以前声明的类型的新方法。
因此,例如,对于基于继承的Vector3
,代码Vector3<float> res = Vector<float, 3U>();
将失败,但如果Vector3
是类型别名:
template<typename T> using Vector3 = Vector<T, 3U>;
然后代码Vector3<float> res = Vector<float, 3U>();
将成功,因为左侧和右侧的类型之间不再不匹配:使用类型别名意味着Vector3<float>
不是从Vector<float, 3U>
继承的,它是类型Vector<float, 3U>
。
- 继承函数的重载解析
- 重载继承的构造函数
- C++中的函数重载和继承
- C++ 继承:基类中重载 operator+ 的 2 次在派生类中无法正常工作
- 如何调用继承的重载运算符<<并在派生类的输出中添加更多文本?
- 类继承和运算符重载
- 通过继承重载运算符会导致歧义
- 使用继承的指针列表复制构造函数或重载运算符=
- 重载<<无法访问继承的私有数据
- C++:涉及继承和"using"时的方法重载
- C++具有多重继承的构造函数重载解析
- c++ 中的函数重载如何在没有钻石继承的情况下工作?
- 函数不参与继承中的重载解析
- 继承类 C++ 中的重载>>
- 模板和unique_ptr继承情况下的重载解决方案
- 如何将同名的继承函数视为重载函数
- 继承重载函数:需要命名空间
- 派生类没有从基类继承重载方法
- c++继承+重载
- c++继承重载成员