Rel*_*lla 1 c++ oop copy class operators
所以有
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;
};
Run Code Online (Sandbox Code Playgroud)
如何实现"复制构造函数"和"赋值运算符"?(抱歉 - 我是C++ nube)
更新:sbi和其他人问 - 为什么我要手动处理原始内存?我的答案很简单 - 在学生项目中,我现在使用了很多C库,例如OpenCV OpenAL和FFmpeg,还有更多.目前使用C++我们尝试创建一个基于图形的直接显示,如跨平台库,这将有助于实时视频广播和处理.我们的图元素目前使用char*和int对进行数据交换.要将数据转换为订阅元素,我们现在使用原始memcpy.我想更进一步,让我们可以使我们的图元素基于C++模板.因此,一个图元素将能够与其他Graph元素共享当前图元素数据,并且它共享的数据将是一个结构,其中不包含一个char*one int,而是包含任意数量的数据字段和几乎任何内部元素.这就是为什么我需要了解如何创建一个实现"复制构造函数"和"赋值运算符"的基本C++结构,以便我能够使用新的数据转换算法,如
void CastData(T item){
for(size_t i = 0 ; i < FuncVec.size(); i++){
T dataCopy = item;
FuncVec[i](dataCopy);
}
}
Run Code Online (Sandbox Code Playgroud)
而不是目前使用
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;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用std::string,而不是char*,您甚至不需要编写operator=或复制构造函数.编译器生成的代码可以很好地完成您的工作.
但作为一般解决方案(对于其他一些场景),请使用复制和交换习惯用法:
例外C++通过香草萨特 非常详细描述了这些.我建议你阅读这本书中的内容.目前,您可以在线阅读本文:
您可能想要解释为什么要手动处理原始内存.我很久没有这样做了,它是为什么std::string以及std::vector在哪里设计的:
struct ResultStructure
{
// nothing else needed
std::string data; // or std::vector<char>
};
Run Code Online (Sandbox Code Playgroud)
但是,如果你真的需要这么做(这是家庭作业吗?),那么首先要知道这是非常难以做到这一点.例如,赋值运算符的简单实现可能如下所示:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
如果有人意外地将一个对象分配给自己(如果你拥有的是两个引用并且你不怀疑它们引用同一个对象,则可能会发生这种情况),那么这将导致致命的失败.
另外,如果new抛出异常怎么办?(std::bad_alloc如果内存耗尽,它可能会抛出.)然后我们已经删除了旧数据并且没有分配新数据.然而,指针仍指向旧数据的位置(实际上,我认为这是实现定义的,但我还没有看到删除后更改ptr的实现),以及类的析构函数(你知道)那个类需要一个析构函数,对吗?)然后会尝试在没有分配数据的地址删除一段数据.这是未定义的行为.你可以期待的最好的是它会立即崩溃.
最简单的方法是使用Copy-And-Swap习语:
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;
};
Run Code Online (Sandbox Code Playgroud)
请注意,我添加了一个析构函数,更改了赋值运算符以传递每个副本的参数(我们需要调用复制构造函数来分配内存),并添加了一个swap成员函数.按照惯例,swap()函数永远不会抛出并且很快,最好是O(1).
我知道GMan对Copy-And-Swap成语的讨论已经足够详尽,而且虽然对我来说可能太简洁了,但你最初可能不会理解很多,但是要坚持并理解为尽可能多.
| 归档时间: |
|
| 查看次数: |
1380 次 |
| 最近记录: |