问题描述
这是对我之前在此处 (C++ vector of class objects and dynamic memory allocation) 发布的问题的跟进。
就本例而言,Someclass
是一个过于简化的类。重要的是要知道此类的对象存储在其他地方的向量中。
Buffer
是另一个具有三种成员类型的类:常规变量(NAME)、向量(S)和指向动态分配的内存块(DATA)的指针。
如果我注释 v.erase(v.begin()+1);
行,则代码编译并运行良好。 Bur erase
会产生许多错误,例如“使用已删除的函数 Buffer& Buffer::operator=(const Buffer&)
”。
我想我明白这个问题,但不知道如何解决它。你能修改我的例子以使其工作吗?请注意,该示例过于简单,我需要保留这两个类并使用向量。
谢谢。
using namespace std;
#include <cstdlib>
#include <vector>
#include <string>
using namespace std;
class Someclass
{
public:
int I;
Someclass(int i) {I = i;};
private:
};
class Buffer
{
public:
vector <Someclass> S;
string NAME;
float *DATA;
Buffer(int length,string name) {DATA = (float*) calloc (length,sizeof(float)); NAME = name;};
Buffer(const Buffer &buffer) = delete;
Buffer(Buffer&& buffer) {
S = buffer.S;
NAME = buffer.NAME;
DATA = buffer.DATA;
buffer.DATA = nullptr;
}
~Buffer(){
S.clear();
if (DATA) free(DATA);
};
private:
};
int main(int argc,char** argv)
{
vector <Buffer> v;
for (int i =0; i<10; i++)
{
cout<<i<<endl;
v.push_back(Buffer(1000,"name"));
}
v.erase(v.begin()+1);
v.clear();
return 0;
}
解决方法
这是因为一个简单的原因。当您擦除一个条目时,阵列需要移除那个“气泡”(即空槽)并压缩阵列。这意味着它需要移动一些东西。所以在移动时,他们所做的就是这样,
// Form the MSVC xutility.h file.
for (; _First != _Last; ++_Dest,(void) ++_First) {
*_Dest = _STD move(*_First);
}
如您所见,他们移动它的方式是移动单个条目。这意味着您调用对象 Buffer
的复制赋值/移动赋值运算符。但是您还没有定义任何赋值运算符,而是定义了一个移动构造函数。这告诉编译器,
“嘿,这个 Buffer 对象只有一个移动构造函数。也许用户只是想通过移动另一个来构造类。所以它不能有任何其他赋值(复制和移动)”
所以现在编译器不会为你生成它们。这意味着您现在不能将另一个 Buffer
复制或移动到另一个(除非您移动构造它)。这就是错误的原因。
解决方案是添加一个移动赋值运算符。
Buffer& operator=(Buffer&& other)
{
S = std::move(other.S);
NAME = std::move(other.NAME);
DATA = other.DATA;
other.DATA = nullptr; // Make sure to set it to nullptr.
return *this;
}