C++ 运算符重载和继承

标签 c++ debugging inheritance operator-overloading

我将从代码开始,因为它更容易解释。

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>;

i have overloaded '[]', '==' and '!=' and it seems to work without a problem,

问题是 operator+您正在返回父类型 Vector<float,3U> , 然后尝试在子类型 Vector3<float> 中使用该类型是必需的。

operator[]你大概会回来 T&然后在 T& 中使用它是必须的。和 operator!=operator==你回来了bool并在 bool 中使用它是必须的。你看得到差别吗?你明白为什么吗:

Vector3<float> res = Vector3<float>();

作品和

Vector3<float> res = Vector<float, 3U>();

不是吗?

Can you please explain further on what type aliases are, and how it can improve the above implementation, and why it would.

您可以在 many 中了解它们的内容。 places .对于您的使用而言,它们的重要之处在于它们不会创建新类型,它们只是创建一种新方法来引用先前声明的类型。

因此,例如,您的继承基于 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++ 运算符重载和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26315909/

相关文章:

c++ - 这个构造函数在做什么?

c++ - 这两个类型测试对象动态数组声明之间的区别?

c++ - c++模板中的一行区别

c# - 如何调试具有异步数据访问且没有调用堆栈的 WPF 应用程序?

c# - Where() 在抽象层返回新的 self

css - 具有不同属性的颜色继承

c++ - std::count 和 std::find 之间的性能差异

ruby - 我应该在我的 Ruby (JRuby) 代码中放入什么来打断调试器?

ios - 我如何解决 'NSUnknownKeyException' ... setValue :forUndefinedKey:]: . ..不符合键值编码

c++ - 显式类型标识符与 RTTI