C++将unique_ptr移动到结构成员
C++ moving a unique_ptr to a struct member
我有以下程序 -
#include <iostream>
#include <memory>
class Person
{
public:
Person(const std::string& name):
name(name) { }
~Person() { std::cout << "Destroyed" << std::endl; }
std::string name;
};
typedef struct _container
{
std::unique_ptr<Person> ptr;
}CONTAINER;
void func()
{
CONTAINER* c = static_cast<CONTAINER*>(malloc(sizeof(CONTAINER)));
std::unique_ptr<Person> p(new Person("FooBar"));
c->ptr = std::move(p);
std::cout << c->ptr->name << std::endl;
}
int main()
{
func();
getchar();
return 0;
}
程序打印"FooBar"。我希望程序在 func() 返回时打印"已销毁",但它没有。有人可以帮助我为什么在这种情况下不会发生这种情况吗?
你实际上在这里有未定义的行为。 不能只将 malloc'd 缓冲区强制转换为对象类型。永远不会调用构造函数,并且成员变量处于无效状态。
您需要执行以下任一操作:
void func()
{
CONTAINER c;
std::unique_ptr<Person> p(new Person("FooBar"));
c.ptr = std::move(p);
std::cout << c.ptr->name << std::endl;
}
或
void func()
{
CONTAINER * c = new CONTAINER();
std::unique_ptr<Person> p(new Person("FooBar"));
c->ptr = std::move(p);
std::cout << c->ptr->name << std::endl;
delete c;
}
或者如果你真的想使用 malloc - 你需要使用放置 new 来获得正确的行为 - 但通常你不希望这样,所以我现在不会详细说明......
您忘记在func()
末尾添加此行。
delete c;
这是测试(IDONE)。
c
是一个原始指针。 它不是一个聪明的指针。 因此,您必须手动删除它。
删除c
将自动删除CONTAINER::ptr
CONTAINER::ptr
因为这是一个唯一的指针。
但是,您必须自己malloc
,更合适的代码可能是:-
c->~_container();
然后free()
,但我认为在这种情况下不需要它,因为CONTAINER
不在堆上。
(我从来没有用过malloc
,所以这部分我不确定。
编辑:
我的解决方案是解决单个问题的快速补丁。 (不打印"已销毁")
另请阅读迈克尔·安德森的解决方案。
它解决了OP代码的另一个基本问题。(马洛克)
编辑2:这里有一个关于迈克尔安德森提到的新放置的好链接。
下面的代码是从链接复制的(几乎没有修改):-
int main(int argc, char* argv[]){
const int NUMELEMENTS=20;
char *pBuffer = new char[NUMELEMENTS*sizeof(A)];
//^^^ difference : your "CONTAINER" could be char[xxxx] (without new)
A *pA = (A*)pBuffer;
for(int i = 0; i < NUMELEMENTS; ++i) {
pA[i] = new (pA + i) A();
}
printf("Buffer address: %x, Array address: %xn", pBuffer, pA);
// dont forget to destroy!
for(int i = 0; i < NUMELEMENTS; ++i){
pA[i].~A();
}
delete[] pBuffer;//<--- no need to delete char[] if it is a stack variable
return 0;
}
有关更多详细信息,请参阅上面的链接(因为我不想将更多内容复制到此处)。
这是另一个有用的链接:通常不建议在C++中使用malloc。
相关文章:
- 具有结构成员char数组的sscanf
- 仅使用结构名称访问结构成员
- 使用 structType*& 赋给结构成员
- 使用结构成员指针在C++中填充结构
- 聚合初始化,将成员指针设置为同一结构成员
- 为什么结构化绑定不使用"auto&"返回对结构成员的引用,而是返回成员本身
- 是否可以将结构数组别名为结构成员数组?
- 结构成员在访问时被清除
- 如何指示结构成员没有锯齿?
- 为什么继承的结构成员在联合中无法访问?
- 尝试在 qml 中访问结构成员的 QList
- C++/CLI -- 访问结构成员
- 调用在类中声明的结构成员
- 对结构成员的临时绑定引用
- 无法使用 strcpy 将字符串复制到静态结构成员
- 为什么类成员数据必须是静态的才能被模板化类的模板化结构成员访问
- 填充模板化结构类型的结构成员
- C/C++intellisense 0.26.1不显示结构成员列表
- 在源文件中创建具有结构成员的结构
- 如何访问结构成员作为指针