如何在C ++中定义和使用=运算符 [英] How to define and use the = operator in C++

查看:114
本文介绍了如何在C ++中定义和使用=运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好。

我做了=运算符并在VC ++中使用。



定义如下:

Hi,all.
I have made = operator and use in VC++.

The definition is as follows:

class CMain
{
public:
  CMain(int nDim)
  {
    dim = nDim;
    pK = new int[nDim];
    memset(pK, 0, sizeof(int) * nDim);
  }
  ~CMain()
  {
    if(pK != NULL)
    {
      delete[] pK;
      pK = NULL;
    }
  }
  CMain& operator(CMain& other)
  {
    dim = other.dim;
    delete[] pK;
    pK = new int[dim];
    memcpy(pK, other.pK, sizeof(int) * dim);
    return *this;
  }
  int dim;
  int* pK;
};



和其他cpp文件中,我的代码如下:


and in other cpp file, my code is as follow:

void main()
{
std::vector<CMain> pTemp(5, CMain(3));

for(int i = 0; i < 5; i++)
{
  CMain m(3);
  m.pK[0] = i;
  m.pK[1] = i;
  m.pK[2] = i;
  
  pTemp[i] = m;
}
CMain mm(3);
for(int i = 0; i < 5; i++)
{
  if(pTemp[i].pK[1] == 2)
    mm = pTemp[i];
}
}



为什么我的代码存储器错误?

我的=运算符错误?

谢谢。


Why does my code memory error?
Is my = operator mistake?
Thanks.

推荐答案

你没有(重新)为你的类定义赋值运算符(你的代码甚至没有编译)。您必须(重新)定义赋值运算符和复制构造函数以避免灾难性故障,例如

You didn't (re-)define the assignment operator for your class (your code doesn't even compile). You have to (re-)define both the assignment operator and the copy constructor in order to avoid catastrophic failures, e.g.
CMain (const CMain & other) // copy ctor
{
  clone(other);
}
CMain & operator = (const CMain & other) // assignment operator
{
  clone(other);
  return *this;
}

void clone( const CMain & other )
{
  dim = other.dim;
  if ( pK )
    delete[] pK;
  pK = new int[dim];
  memcpy(pK, other.pK, sizeof(int) * dim);
}





无论如何,请注意,最好使用向量< int> ;< / int> 而不是 CMain 类中的手工制作数组。



In any case, please note, it would be better use a vector<int></int> instead of the handcrafted array inside your CMain class.


首先你有忘记C字头 - 它的丑陋而且它不是大多数人认为的符号的符号。



现在你的问题。你只在这里做一个浅拷贝:pTemp [i] = m;像memcpy。因此当m超出范围时,CMain的析构函数被调用。析构函数现在删除你在consturctor中分配的数组,结果是,pK在pTemp [i]中失效。



编辑:

这是不应该的:

用pTemp [i] = std :: move(m)替换pTemp [i] = m应解决它。



您必须定义自己的移动赋值运算符,完整的工作程序:

Firstly you have to forget the C-prefix - its ugly and its not part of the ungary notation how the most of people think.

Now to your problem. You only make a shallow copy here: pTemp[i] = m; like memcpy. So when m gets out of scope the destructor of CMain gets called. The destructor now deletes the array you allocated before in the consturctor, the result of that is, that pK gets invalid in pTemp[i].


This isn't enought:
Replacing pTemp[i] = m with pTemp[i] = std::move(m) should solve it.

You have to define your own move assignment operator, the full working program:
#include <vector>
#include <cstring>

class CMain
{
public:
	CMain(int nDim)
	{
		dim = nDim;
		pK = new int[nDim];
		memset(pK, 0, sizeof(int) * nDim);
	}
	~CMain()
	{
		if (pK != NULL)
		{
			delete[] pK;
			pK = NULL;
		}
	}
	CMain& operator() (CMain& other)
	{
		dim = other.dim;
		delete[] pK;
		pK = new int[dim];
		memcpy(pK, other.pK, sizeof(int) * dim);
		return *this;
	}
	CMain& operator=(CMain&& other)
	{
		dim = other.dim;
		pK = other.pK;
		other.pK = nullptr;
		return *this;
	}
	int dim;
	int* pK;
};

int main(int argc, char* argv[])
{
	std::vector<CMain> pTemp(3, CMain(3));
	for (int i = 0; i < 3; i++)
	{
		CMain m(1);
		m.pK[0] = i;
		m.pK[1] = i;
		m.pK[2] = i;
		pTemp[i] = std::move(m);
	}
	CMain mm(3);
	for (int i = 0; i < 3; i++)
	{
		if (pTemp[i].pK[1] == 2)
			mm = std::move(pTemp[0]);
	}
	return 0;
}



或者如果你需要指向同一个对象的多个指针,你可以将ptr存储在一个globaly对象中,最好是作为normaly对象实例化并从你的指向它们CMain-Objects或您使用std :: shared_ptr< int []>使用自定义析构函数。



C ++很难学习^^


Or if you need multyple pointer to the same object either your store the ptr in a globaly object preferably instanced as normaly object and point to them from your CMain-Objects or you use an std::shared_ptr<int[]> with an custom destructor.

C++ is hard to learn^^


我不完全确定...有你尝试:=而不是=
I'm not complete sure ... have you tried := instead of =


这篇关于如何在C ++中定义和使用=运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆