C++ c++;运算符=工作异常(函数内部输出正常,但返回后输出错误..)

C++ c++;运算符=工作异常(函数内部输出正常,但返回后输出错误..),c++,object,C++,Object,我有一个程序,我一直在修改以提取一些数据。 最近,我又做了一次数据提取,由于时间不够,我使用了一种变通方法。 现在,我正试图找出问题所在,因为我有一些空闲时间 下面有一个函数Act(),它是Mat类的成员函数,它用更改的数据值形成一个新的矩阵。Mat有一个指向包含实际数据的缓冲区的指针。我发现在返回矩阵的Act()函数之后,调用了“operator=”函数。(没有操作符=)函数,所以我添加了它。也许默认的'=操作符'被使用。有或没有我的“操作符=”函数,它不产生最终的正确输出。这里是'='操作符

我有一个程序,我一直在修改以提取一些数据。
最近,我又做了一次数据提取,由于时间不够,我使用了一种变通方法。
现在,我正试图找出问题所在,因为我有一些空闲时间

下面有一个函数Act(),它是Mat类的成员函数,它用更改的数据值形成一个新的矩阵。Mat有一个指向包含实际数据的缓冲区的指针。我发现在返回矩阵的Act()函数之后,调用了“operator=”函数。(没有操作符=)函数,所以我添加了它。也许默认的'=操作符'被使用。有或没有我的“操作符=”函数,它不产生最终的正确输出。这里是'='操作符返回数据(类型MAT)的部分。(它是C++代码,但我只是使用了Prtf,因为它工作)无论如何< /P>
原始代码有什么问题?

operator=应该修改*这一点,而不是创建新的临时对象X,将接收到的数据复制到X,然后返回X。您已经创建了一个临时对象,但运行operator=的类的数据尚未修改

请尝试以下代码:

template<typename T>
Mat<T> Mat<T>::operator = (const Mat<T>& rhs)
{
  int num_bytes = sizeof(T) * rhs.row_ * rhs.col_;
  printf("ope = , res val = %x, src val = %x, row = %d, col = %d\n", this->val_, rhs.val_, rhs.row_, rhs.col_);
  for(int i=0;i<10;i++){
    printf("%04x ",((half_float::half *)rhs.val_)[i].data_);
    }
  printf("\n");
  memcpy(this->val_, rhs.val_, num_bytes);
  for(int i=0;i<10;i++){
    printf("%04x ",((half_float::half *)this->val_)[i].data_);
    }
  printf("\n");
  return *this;
}
模板
Mat::operator=(常数Mat和rhs)
{
int num_bytes=sizeof(T)*rhs.row_*rhs.col;
printf(“ope=,res val=%x,src val=%x,行=%d,列=%d\n”,this->val,rhs.val,rhs.row,rhs.col);
for(int i=0;ival_,rhs.val_,num_字节);
对于(int i=0;ival_ui)[i]。数据;
}
printf(“\n”);
归还*这个;
}
a=a.Act()
不起作用,因为您错误地实现了
运算符=
。默认的
操作符=
在这种情况下不起作用,因为类中有一个指针,当
Act()
返回的临时值被销毁时,它可能会使指针无效

调用了
操作符=
,因为您在代码中编写了
=
。当您使用“tmp解决方案”时,您将创建一个新对象,它不调用
操作符=
,而是调用复制构造函数。这似乎奏效了

至于如何正确实现
操作符=
:赋值操作符应该修改现有对象,而不是返回新对象

例如:

struct A {
    int row_, col_;
    float *val_;

    A& operator=(const A& rhs) {
        if (this != &rhs) {
            const int num_bytes = sizeof(float) * rhs.row_ * rhs.col_;
            row_ = rhs.row_;
            col_ = rhs.col_;
            memcpy(val_, rhs.val_, num_bytes);
        }
        return *this;
    }
};

由于注释的状态正确,注释旨在修改已存在的对象。你正在创建一个新的并返回它

试着这样做:

template<typename T>
Mat<T>& Mat<T>::operator = (const Mat<T>& rhs)
{
  row_ = rhs.row_;
  col_ = rhs.col_;
  delete val_;
  val_ = new T[row_*col_];

  int num_bytes = sizeof(T) * rhs.row_ * rhs.col_;
  printf("ope = , res val = %x, src val = %x, row = %d, col = %d\n", val_, rhs.val_, rhs.row_, rhs.col_);
  for(int i=0;i<10;i++){
    printf("%04x ",((half_float::half *)rhs.val_)[i].data_);
    }
  printf("\n");
  memcpy(val_, rhs.val_, num_bytes);
  for(int i=0;i<10;i++){
    printf("%04x ",((half_float::half *)val_)[i].data_);
    }
  printf("\n");
  return *this;
}
模板
材料和材料::运算符=(材料和材料常数)
{
row_uu=rhs.row_uu;
col_uu2;=rhs.col_2;;
删除valu;
val_uut=新的[行*列];
int num_bytes=sizeof(T)*rhs.row_*rhs.col;
printf(“ope=,res val=%x,src val=%x,行=%d,列=%d\n”,val,rhs.val,rhs.row,rhs.col);

对于(int i=0;iAssignment应该修改
*此
,而不是创建新对象。生成正确输出的代码不是赋值,而是初始化。(您需要阅读“三法则”。)所有这些都包含在…中,这使得我认为这是一个复制和交换习惯用法的实现,它忘记了“交换”。此外,考虑使用复制和交换习语,而不是手写的<代码>运算符=< /Cord> @ MulbDNILO。也许我不知道一些重要的事情。我想保持ACTHER()函数(返回一个新的对象)。,那么我不能用'a=a.Act()'替换a吗?为什么要调用'=运算符?@ChanKim我不知道你在想什么。如果你重载了运算符,
a=a.Act()
将被转换为
a.operator=(a.Act())
(请注意,返回值未使用)哇,这很管用。我不知道
操作符=
应该返回
*this
:)。我意识到如果我使用'a=',那么
操作符=
将用于
a
,我需要在那里实现
深度复制。谢谢!谢谢!这也是答案。但是我看到了另一个,并首先选择了它,对不起。(另一个给了我一些其他的解释。):)
d0_out = d0_out.Act(NN_CELL::AT_TANH);   
template<typename T>
Mat<T> Mat<T>::operator = (const Mat<T>& rhs)
{
  int num_bytes = sizeof(T) * rhs.row_ * rhs.col_;
  printf("ope = , res val = %x, src val = %x, row = %d, col = %d\n", this->val_, rhs.val_, rhs.row_, rhs.col_);
  for(int i=0;i<10;i++){
    printf("%04x ",((half_float::half *)rhs.val_)[i].data_);
    }
  printf("\n");
  memcpy(this->val_, rhs.val_, num_bytes);
  for(int i=0;i<10;i++){
    printf("%04x ",((half_float::half *)this->val_)[i].data_);
    }
  printf("\n");
  return *this;
}
struct A {
    int row_, col_;
    float *val_;

    A& operator=(const A& rhs) {
        if (this != &rhs) {
            const int num_bytes = sizeof(float) * rhs.row_ * rhs.col_;
            row_ = rhs.row_;
            col_ = rhs.col_;
            memcpy(val_, rhs.val_, num_bytes);
        }
        return *this;
    }
};
template<typename T>
Mat<T>& Mat<T>::operator = (const Mat<T>& rhs)
{
  row_ = rhs.row_;
  col_ = rhs.col_;
  delete val_;
  val_ = new T[row_*col_];

  int num_bytes = sizeof(T) * rhs.row_ * rhs.col_;
  printf("ope = , res val = %x, src val = %x, row = %d, col = %d\n", val_, rhs.val_, rhs.row_, rhs.col_);
  for(int i=0;i<10;i++){
    printf("%04x ",((half_float::half *)rhs.val_)[i].data_);
    }
  printf("\n");
  memcpy(val_, rhs.val_, num_bytes);
  for(int i=0;i<10;i++){
    printf("%04x ",((half_float::half *)val_)[i].data_);
    }
  printf("\n");
  return *this;
}