模板、继承和运算符

发布于 2024-12-22 19:55:24 字数 1902 浏览 2 评论 0原文

我在类模板继承和运算符(运算符 +)方面遇到一些麻烦, 请看一下这些行:

基本向量类 (TVector.h):

template<class Real, int Size>
class TVector {
protected:
    Real* values;
public:

    ...

    virtual TVector<Real, Size>& operator=(const TVector<Real, Size>& rTVector) { //WORKS
        int i = 0;
        while (i<Size) {
            *(values+i) = *(rTVector.values+i);
            i++;
        }
        return *this;
    }
    virtual TVector<Real, Size> operator+(const TVector<Real, Size>& rTVector) const {
        int i = 0;
        Real* mem = (Real*)malloc(sizeof(Real)*Size);
        memcpy(mem, values, Size);
        while (i<Size) {
            *(mem+i) += *(rTVector.values+i);
            i++;
        }
        TVector<Real, Size> result = TVector<Real, Size>(mem);
        free(mem);
        return result;
    }
};

2D 矢量类 (TVector2.h):

template<class Real>
class TVector2: public TVector<Real, 2> {
public:

    ...

    TVector2& operator=(const TVector2<Real>& rTVector) { //WORKS
        return (TVector2&)(TVector<Real, 2>::operator=(rTVector));
    }
    TVector2 operator+(TVector2<Real>& rTVector) const { //ERROR
        return (TVector2<Real>)(TVector<Real, 2>::operator+(rTVector));
    }
};

测试 (main.cpp):

int main(int argc, char** argv) {
    TVector2<int> v = TVector2<int>();
    v[0]=0;
    v[1]=1;
    TVector2<int> v1 = TVector2<int>();
    v1.X() = 10;
    v1.Y() = 15;
    v = v + v1; //ERROR ON + OPERATOR
    return 0;
}

编译错误 (VS2010):

错误 2 错误 C2440: 'cast de type': 无法转换自 'TVector<真实,大小>'到“TVector2”...

这里出了什么问题?有办法做这种事情吗? 只是寻找一种不重新定义我所有 Vectors 类的方法。 我一直在努力做到这一点,但我很高兴能从你们那里得到一些帮助。

抱歉英语不好, 此致。

I have some trouble with class template inheritance and operators (operator +),
please have a look at these lines:

Base vector class (TVector.h):

template<class Real, int Size>
class TVector {
protected:
    Real* values;
public:

    ...

    virtual TVector<Real, Size>& operator=(const TVector<Real, Size>& rTVector) { //WORKS
        int i = 0;
        while (i<Size) {
            *(values+i) = *(rTVector.values+i);
            i++;
        }
        return *this;
    }
    virtual TVector<Real, Size> operator+(const TVector<Real, Size>& rTVector) const {
        int i = 0;
        Real* mem = (Real*)malloc(sizeof(Real)*Size);
        memcpy(mem, values, Size);
        while (i<Size) {
            *(mem+i) += *(rTVector.values+i);
            i++;
        }
        TVector<Real, Size> result = TVector<Real, Size>(mem);
        free(mem);
        return result;
    }
};

2D vector class (TVector2.h):

template<class Real>
class TVector2: public TVector<Real, 2> {
public:

    ...

    TVector2& operator=(const TVector2<Real>& rTVector) { //WORKS
        return (TVector2&)(TVector<Real, 2>::operator=(rTVector));
    }
    TVector2 operator+(TVector2<Real>& rTVector) const { //ERROR
        return (TVector2<Real>)(TVector<Real, 2>::operator+(rTVector));
    }
};

Test (main.cpp):

int main(int argc, char** argv) {
    TVector2<int> v = TVector2<int>();
    v[0]=0;
    v[1]=1;
    TVector2<int> v1 = TVector2<int>();
    v1.X() = 10;
    v1.Y() = 15;
    v = v + v1; //ERROR ON + OPERATOR
    return 0;
}

Compilation error (VS2010):

Error 2 error C2440: 'cast de type' : cannot convert from
'TVector<Real,Size>' to 'TVector2' ...

What is wrong here ? is there a way to do this kind of stuff ?
Just looking for a way to not redefine all my Vectors classes.
I keep searching to do it, but I will be glad to get some help from you guys.

Sorry for bad English,
Best regards.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暮凉 2024-12-29 19:55:24
#include <memory>

using namespace std;

template<class Real, int Size> class TVector {
protected:
  Real *_values;
public:
  TVector() {
    // allocate buffer
    _values = new Real[Size];
  }
  TVector(Real *prValues) {
    // check first
    if (prValues == 0)
      throw std::exception("prValues is null");
    // allocate buffer
    _values = new Real[Size];
    // initialize buffer with values
    for (unsigned int i(0U) ; i < Size ; ++i)
      _values[i] = prValues[i];
  }
  // Do not forget copy ctor
  TVector(TVector<Real, Size> const &rTVector) {
    // allocate buffer
    _values = new Real[Size];
    // initialize with other vector
    *this = rTVector;
  }
  virtual ~TVector() {
    delete [] _values;
  }
  virtual Real &operator[](int iIndex) {
    // check for requested index
    if (iIndex < 0 || iIndex >= Size)
      throw std::exception("requested index is out of bounds");
    // index is correct. Return value
    return *(_values+iIndex);
  }
  virtual TVector<Real, Size> &operator=(TVector<Real, Size> const &rTVector) {
    // just copying values
    for (unsigned int i(0U) ; i < Size ; ++i)
      _values[i] = rTVector._values[i];
    return *this;
  }
  virtual TVector<Real, Size> &operator+=(TVector<Real, Size> const &rTVector) {
    for (unsigned int i(0U) ; i < Size ; ++i)
      _values[i] += rTVector._values[i];
    return *this;
  }
  virtual TVector<Real, Size> operator+(TVector<Real, Size> const &rTVector) {
    TVector<Real, Size> tempVector(this->_values);
    tempVector += rTVector;
    return tempVector;
  }
};

template<class Real> class TVector2: public TVector<Real, 2> {
public:
  TVector2() {};
  TVector2(Real *prValues): TVector(prValues) {}
  TVector2 &operator=(TVector2<Real> const &rTVector) {
    return static_cast<TVector2 &>(TVector<Real, 2>::operator=(rTVector));
  }
  TVector2 &operator+=(TVector2<Real> const &rTVector) {
    return static_cast<TVector2 &>(TVector<Real, 2>::operator+=(rTVector));
  }
  TVector2 operator+(TVector2<Real> const &rTVector) {
    return static_cast<TVector2 &>(TVector<Real, 2>::operator+(rTVector));
  }
  Real &X() { return _values[0]; }
  Real &Y() { return _values[1]; }
};

int main(int argc, char** argv) {
  TVector2<int> v = TVector2<int>();
  v[0]=0;
  v[1]=1;
  TVector2<int> v1 = TVector2<int>();
  v1.X() = 10;
  v1.Y() = 15;
  v = v1;
  v += v1;
  v = v + v1;
  return 0;
}

一些杂项注释:

  1. 使用 malloc 来对抗 new 是非常糟糕的。 Real 只能是 POD,以便让 vector 在您的情况下正常工作。如果您认为 malloc 在 POD 上提供了更好的性能,请使用 new 或提供自定义创建策略。另外,在销毁内存缓冲区时,不要忘记使用 delete [] 而不是 free
  2. 最好在重载 operator[] 时执行边界检查,
  3. 以获得更好的性能,使用 ++i 而不是后缀形式。前者不会创造临时价值。
#include <memory>

using namespace std;

template<class Real, int Size> class TVector {
protected:
  Real *_values;
public:
  TVector() {
    // allocate buffer
    _values = new Real[Size];
  }
  TVector(Real *prValues) {
    // check first
    if (prValues == 0)
      throw std::exception("prValues is null");
    // allocate buffer
    _values = new Real[Size];
    // initialize buffer with values
    for (unsigned int i(0U) ; i < Size ; ++i)
      _values[i] = prValues[i];
  }
  // Do not forget copy ctor
  TVector(TVector<Real, Size> const &rTVector) {
    // allocate buffer
    _values = new Real[Size];
    // initialize with other vector
    *this = rTVector;
  }
  virtual ~TVector() {
    delete [] _values;
  }
  virtual Real &operator[](int iIndex) {
    // check for requested index
    if (iIndex < 0 || iIndex >= Size)
      throw std::exception("requested index is out of bounds");
    // index is correct. Return value
    return *(_values+iIndex);
  }
  virtual TVector<Real, Size> &operator=(TVector<Real, Size> const &rTVector) {
    // just copying values
    for (unsigned int i(0U) ; i < Size ; ++i)
      _values[i] = rTVector._values[i];
    return *this;
  }
  virtual TVector<Real, Size> &operator+=(TVector<Real, Size> const &rTVector) {
    for (unsigned int i(0U) ; i < Size ; ++i)
      _values[i] += rTVector._values[i];
    return *this;
  }
  virtual TVector<Real, Size> operator+(TVector<Real, Size> const &rTVector) {
    TVector<Real, Size> tempVector(this->_values);
    tempVector += rTVector;
    return tempVector;
  }
};

template<class Real> class TVector2: public TVector<Real, 2> {
public:
  TVector2() {};
  TVector2(Real *prValues): TVector(prValues) {}
  TVector2 &operator=(TVector2<Real> const &rTVector) {
    return static_cast<TVector2 &>(TVector<Real, 2>::operator=(rTVector));
  }
  TVector2 &operator+=(TVector2<Real> const &rTVector) {
    return static_cast<TVector2 &>(TVector<Real, 2>::operator+=(rTVector));
  }
  TVector2 operator+(TVector2<Real> const &rTVector) {
    return static_cast<TVector2 &>(TVector<Real, 2>::operator+(rTVector));
  }
  Real &X() { return _values[0]; }
  Real &Y() { return _values[1]; }
};

int main(int argc, char** argv) {
  TVector2<int> v = TVector2<int>();
  v[0]=0;
  v[1]=1;
  TVector2<int> v1 = TVector2<int>();
  v1.X() = 10;
  v1.Y() = 15;
  v = v1;
  v += v1;
  v = v + v1;
  return 0;
}

Some misc notes:

  1. it's very bad that you use malloc against of new. Real can be POD only to allow vector work well in your case. Use new or provide custom creation policy if you think that malloc provides better performance on PODs. Also do not forget to use delete [] instead of free while destroying memory buffer.
  2. It's better to perform bounds checking while overloading operator[]
  3. for better performance use ++i instead of postfix form. In former no temporary value is created.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文