找出C++中的值语义
figuring out value semantics in C++
我有一个包含以下成员的类字符串:
Class String{
...
private:
char* word
int length
}
String 的复制赋值返回一个 String&,并在堆上分配单词。
我还有一个用 C 编写的链表类,它有一个函数:
void *popFront(struct List *list)
{
struct Node prevHead = list->head
list->head = prevHead->next;
void *info = prevHead->info;
free(prevHead);
return info;
}
我的任务是为使用 C 函数的C++链表编写相同的函数。这是我所拥有的:
String List::popFront()
{
String s = (*(String *) ::popFront(&list));//casting the void * to String
return s;
}
C++ 方法应按值返回对象。这就是我认为该方法可以做到的。然而我有内存泄漏。关于我需要如何修改 List::p opFront() 以便它按值返回的任何提示?谢谢。
首先将返回的指针本地存储为指向字符串的指针,然后创建字符串的本地副本,然后删除对象,指针指向并最终返回本地副本。
编辑:顺便说一句,您可以使用 c++11 的智能指针来避免额外的副本:
String List::popFront()
{
auto s = std::unique_ptr<String>((String*) ::popFront(&list));
return *s;
}
但这可能不是,你的老师的目标。
popFront
从链表中删除元素并释放节点,但不释放info
部分。这是popFront
调用者的责任,例如
String *s = (String *) ::popFront(&list);
delete s;
但是您还必须保留一份副本,您可以从该方法返回该副本
String List::popFront()
{
String *s = (String *) ::popFront(&list);
String tmp = *s;
delete s;
return tmp;
}
你声明String List::popFront()
它返回一个对象,而不是一个指针。String s = ...
声明一个对象,而不是指针或引用。因此,s
赋值会构造一个新对象,s
作为::popFront
返回的内容的副本,然后返回s
的下一个副本并s
本身被销毁。但是,::popFront()
未链接的对象仍保留在堆上,从而产生泄漏。
不要创建String
对象的中间副本,返回指向未链接对象的指针,以便调用方可以将其链接到自己的列表或在使用后delete
它:
String *List::popFront()
{
String *s = (String *) ::popFront(&list);//casting the void * to String *
return s;
}
相关文章:
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- Boost Spirit,获取迭代器内部语义动作
- 可以使用移动语义更改或改进此C++代码吗?
- c++在使用指针时移动语义
- 在C++17中,引用const字符串的语义应该是什么
- Xcode 语义问题引用或以前定义的代码
- 使用移动和复制语义时函数匹配如何工作?
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 移动语义和深层/浅层复制之间有什么关系?
- 了解构造函数在移动、复制、赋值语义中的行为
- std::unique_lock移动语义
- 移动语义和运算符 + 重载
- C++ 移动语义是否在任何情况下都能节省资源?
- 移动语义在这里如何工作?
- 使用移动语义:右值引用作为方法参数
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 在C++中使用移动语义的正确方法是什么?
- C++ 价值语义、不可变性和继承性
- 移动语义 c++ 单链表