我能给出的最好的例子是javascript中的Three.js库:
function createMesh(){
var geometry = new THREE.SphereGeometry(10, 5, 5);
var material = new THREE.MeshPhongMaterial();
var mesh = new Mesh(geometry, material);
return mesh;
}
这在C ++中转换为:
Mesh* createMesh(){
SphereGeometry* geometry = new SphereGeometry(10, 5, 5);
MeshPhongMaterial* material = new MeshPhongMaterial;
Mesh* mesh = new Mesh(geometry, material);
return mesh;
}
现在,谁应该负责删除这3个指针。它应该是图书馆的用户吗?或者应该在Mesh的析构函数中销毁几何和材质,用户应该只删除Mesh指针?如果是这种情况,玩家将如何知道不删除他的指针并避免双重删除?
此外,如果发生这种情况该怎么办:
SphereGeometry geometry(10, 5, 5);
MeshPhongMaterial material;
Mesh* mesh = new Mesh(&geometry, &material);
感谢。
答案 0 :(得分:9)
使用智能指针,所有权很明确:
std::unique_ptr<Mesh> createMesh(){
auto geometry = std::make_unique<SphereGeometry>(10, 5, 5);
auto material = std::make_unique<MeshPhongMaterial>();
return std::make_unique<Mesh>(std::move(geometry), std::move(material));
}
答案 1 :(得分:6)
它应该是图书馆的用户吗?
库缺少有关何时删除这些对象的可靠信息,因此它必须是用户。但他并不需要手动完成(请参阅最后关于智能指针的内容)。
或者应该在Mesh的析构函数中销毁几何体和材质,用户应该只删除网格指针?
在构造函数中转移所有权是一种可行的替代方法。它还允许您将代码“折叠”为更短的内容,而单独删除则无法实现:
Mesh* mesh = new Mesh(new SphereGeometry(10, 5, 5), new MeshPhongMaterial);
如果是这种情况,玩家将如何知道不删除他的指针并避免双重删除?
阅读文档。
此外,如果发生这种情况该怎么办:
Mesh* mesh = new Mesh(&geometry, &material);
只要您未在mesh
和geometry
范围之外提供material
,就不会发生任何事情。
更好的方法是尽可能避免使用原始指针。在实际可行的任何地方使用对象而不是指向对象的指针。需要动态调整大小时使用集合。必须有指针时使用智能指针。