gpt4 book ai didi

c++ - 如何为这种 C++ 结构实现复制运算符?

转载 作者:行者123 更新时间:2023-12-01 15:03:51 25 4
gpt4 key购买 nike

所以有

struct ResultStructure
{
ResultStructure(const ResultStructure& other)
{
// copy code in here ? using memcpy ? how???
}
ResultStructure& operator=(const ResultStructure& other)
{
if (this != &other) {
// copy code in here ?
}
return *this
}
int length;
char* ptr;
};

如何实现“复制构造函数”和“赋值运算符”? (对不起 - 我是 C++ nube)

更新:sbi 和其他人问 - 为什么我要手动处理原始内存?我的答案很简单——在我参与的一个学生项目中,现在我们使用了很多 C 库,例如 OpenCV OpenAL 和 FFmpeg,还有更多。目前使用 C++,我们尝试创建一个基于图形的直接显示,如跨平台库,这将有助于实时视频广播和处理。我们的图形元素目前使用 char* 和 int 对进行数据交换。要将数据转换为订阅的元素,我们现在使用原始 memcpy。我想更进一步,让我们能够将我们的图形元素作为 C++ 模板的基础。因此,一个图形元素将能够与其他图形元素共享当前的图形元素数据,并且它共享的数据将是一种结构,其中不包含一个 char* 一个 int,而是包含任意数量的数据字段和几乎任何内部元素。所以这就是为什么我需要了解如何创建一个实现“复制构造函数”和“赋值运算符”的基本 C++ 结构,以便能够为我们使用新的数据转换算法,例如
void CastData(T item){
for(size_t i = 0 ; i < FuncVec.size(); i++){
T dataCopy = item;
FuncVec[i](dataCopy);
}
}

而不是当前使用的
void CastData(char * data, int length){
for(size_t i = 0 ; i < FuncVec.size(); i++){
char* dataCopy = new char[length];
memcpy(dataCopy, data, length);
FuncVec[i](dataCopy, length);
delete[] dataCopy;
}
}

最佳答案

您可能想解释为什么要手动处理原始内存。好久没做这个了,就是std::stringstd::vector设计用于:

struct ResultStructure
{
// nothing else needed

std::string data; // or std::vector<char>
};

但是,如果您真的需要以艰难的方式做到这一点(这是家庭作业吗?),那么请注意,起初,要做到这一点非常困难。例如,赋值运算符的简单实现可能是这样的:
// DON'T TRY THIS AT HOME!!
ResultStructure& ResultStructure::operator=(const ResultStructure& rhs)
{
delete[] ptr; // free old ressource
ptr = new char[rhs.length]; // allocate new resourse
std::copy(rhs.ptr, rhs.ptr+rhs.length, ptr; // copy data
length = rhs.length;
}

如果有人不小心将一个对象分配给自己(如果您只有两个引用并且您不怀疑它们引用同一个对象,则可能会发生这种情况),那么这将致命地失败。
另外,如果 new抛出异常? (如果内存耗尽,它可能会抛出 std::bad_alloc。)那么我们已经删除了旧数据并且没有分配新数据。然而,指针仍然指向旧数据曾经所在的位置(实际上,我认为这是实现定义的,但我还没有看到在删除时更改 ptr 的实现)和类的析构函数(你知道该类将需要一个析构函数,对吗?)然后将尝试删除未分配数据的地址处的一条数据。那是未定义的行为。您可以期望的最好的结果是它会立即崩溃。

最简单的方法是使用 Copy-And-Swap idiom :
struct ResultStructure
{
ResultStructure(const ResultStructure& other)
: ptr(new char[rhs.length]), length(rhs.length)
{
std::copy(rhs.ptr, rhs.ptr+rhs.length, ptr);
}

~ResultStructure() // your class needs this
{
delete[] ptr;
}

ResultStructure& operator=(ResultStructure rhs) // note: passed by copy
{
this->swap(rhs);
return *this
}

void swap(const ResultStruct& rhs)
{
using std::swap;
swap(length, rhs.length);
swap(ptr, rhs.ptr);
}

std::size_t length;
char* ptr;
};

请注意,我添加了一个析构函数,更改了赋值运算符以传递每个拷贝的参数(我们需要调用复制构造函数来分配内存),并添加了一个 swap成员函数。按照惯例,一个 swap()函数从不抛出并且速度很快,最好是 O(1)。

我知道 GMan's discussion of the Copy-And-Swap idiom mine可能对你来说太简洁了,一开始你可能不会理解很多,但试着坚持下去,尽可能多地理解。

关于c++ - 如何为这种 C++ 结构实现复制运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4848380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com