【问题标题】:Overloading Operators in C++ with a Template使用模板重载 C++ 中的运算符
【发布时间】:2012-09-02 22:11:32
【问题描述】:

我在 C++ 中遇到了运算符重载的问题。

我定义了以下类:

template <class T>
class Array
{
public:
//! Default constructor
Array(int ArraySize = 10);

////! Defualt destructor
Array<T>::~Array();

//! Redefinition of the subscript operator
T& Array<T>::operator[] (int index);

//! Redefinition of the assignment operator
const Array<T>& Array<T>::operator=(const Array<T>&);

//! Redefinition of the unary operator -
Array<T>& operator-(Array<T>& a);

//! Array length
int size;

private:
//! Array pointer
T *ptr;
};

一元运算符 - 定义如下:

//! Redefinition of the unary operator -
template<class T> 
 Array<T>& operator-(Array<T>& a){
    static Array<T> myNewArray(a.size);

    for( int i = 0; i < a.size; i++){
    myNewArray[i]=-a[i];    
    }
    return myNewArray;
}

如何避免“myNewArray”在内存中的持久性?没有“静态”声明 当函数结束并且像 VectorA=-VectorB 这样的赋值失败时,myNewArray 会消失。

第二个问题是关于强制转换运算符的重载;我以这种方式重载了强制转换运算符:

//!CASTING
template <class B>
operator Array<B>(){
    static Array<B> myNewArray(size);

.... a function makes the conversion and returns myNewArray populated...

return myNewArray;
}

但它不起作用!在使用静态声明执行函数后,对象 myNewArray 似乎也消失了。任何像 VectorA=(Array)VectorB 这样的赋值都会失败。

错误在哪里?请大家提出解决方案好吗? 提前谢谢!

【问题讨论】:

  • 对于演员表操作员,再次,不需要static。但是,如果没有编译和运行并显示问题的实际代码,就不可能说出出了什么问题。
  • 尽可能避免使用强制转换运算符。很难预测何时触发隐式强制转换,这会导致很难找到错误。您应该考虑改为使用模板赋值运算符:template &lt;class B&gt; Array&amp; operator=(const Array&lt;B&gt;&amp; rhs)。这将允许您将Array&lt;B&gt; 显式转换为Array&lt;T&gt;
  • 您还可以编写一个模板化的显式构造函数,允许从Array&lt;B&gt; 中显式构造一个Array&lt;T&gt;
  • 您的operator- 不是一元的。它在*thisa 上运行。 VectorA = -VectorB 怎么可能编译?我建议您尝试制作一个实际编译的小代码示例,您可以向我们展示——它总是很有帮助。
  • 谢谢大家!我发现了问题:它是复制构造函数。函数的按值返回和命令 A=f(b) 不起作用,因为复制构造函数错误。重写后一切正常,无需静态和按引用返回。

标签: c++ templates casting operators overloading


【解决方案1】:

对于您的运营商,不要返回参考。返回 myNewArray 的副本。大多数编译器可以省略复制并使用返回值优化来使性能可以接受。

您还应该将这些方法标记为 const,因为它们不会改变状态。

template<class T> 
 Array<T> operator-(const Array<T>& a) {
    Array<T> myNewArray(a.size);

    for( int i = 0; i < a.size; i++){
    myNewArray[i]=-a[i];    
    }
    return myNewArray;
}

【讨论】:

  • @Jupiter 哎呀,少了一个字符。
【解决方案2】:

如果没有“静态”声明 myNewArray 当函数消失 结束并失败任何分配,例如 VectorA=-VectorB。

不,它没有。编译器确保它挂起足够长的时间以被复制。

另外,如果将 myNewArray 初始化为原始的副本,代码会更简洁:

Array<T> myNewArray(a);
for (int i = 0; i < myNewArray.size(); ++i)
    myNewArray[i] *= -1;

【讨论】:

  • 哎呀,正如@EthanSteinberg 指出的那样,由于该函数返回一个引用,因此需要static。不过,最好按值返回
【解决方案3】:

嗯,由于这两个问题都涉及到正确分配新值的神秘失败,所以赋值运算符有什么问题吗?

【讨论】:

  • 这应该是对问题的评论,而不是答案。
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-06
相关资源
最近更新 更多