类对象的 C++ 向量和动态内存分配 - 第 2 部分

问题描述

这是对我之前在此处 (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;
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...