C++ c+中的合成+;使用原始指针还是智能指针?
我想做的一个小例子 我有一个(堆栈分配的)顶点列表 并希望创建一个边列表C++ c+中的合成+;使用原始指针还是智能指针?,c++,oop,smart-pointers,composition,C++,Oop,Smart Pointers,Composition,我想做的一个小例子 我有一个(堆栈分配的)顶点列表 并希望创建一个边列表 class Edge { int id; Vertex * source; Vertex * target; }; 具有指向其源顶点和目标顶点的两个指针 通常我会在这里引用,但我希望能够在运行时更改源顶点或目标顶点,所以我需要某种指针类型 所以我的问题是:这里有一个有用的智能指针吗?或者我应该像上面那样使用一个普通指针吗 编辑 回答中提到的一些问题: 首先,列表应该拥有顶点,这就是它们位于堆栈上
class Edge {
int id;
Vertex * source;
Vertex * target;
};
具有指向其源顶点和目标顶点的两个指针
通常我会在这里引用,但我希望能够在运行时更改源顶点或目标顶点,所以我需要某种指针类型
所以我的问题是:这里有一个有用的智能指针吗?或者我应该像上面那样使用一个普通指针吗
编辑
回答中提到的一些问题:
首先,列表应该拥有顶点,这就是它们位于堆栈上的原因
其次,ID用于另一个程序
它需要一个包含所有顶点及其坐标列表的文件,以及所有边及其两个顶点ID的列表
第三,我需要某种指针,因为顶点的ID在运行时会发生变化,并且边的源顶点和目标顶点可能会更改为
(除其他事项外,还进行了某种切割和切片)成分是什么
组合(在UML术语中)是一种关联,当一个给定对象是另一个对象的“一部分”时,即它具有相同的生命周期,并且最重要和最具特征的东西本身不存在/没有意义 根据这一描述,构图不是我们想要实现的——请参见第二部分。 在C或C++中,实现构图的最好方法是不使用任何指针:
class Edge {
int id;
Vertex source;
Vertex target;
};
这种方法在内存使用方面是最好的(一个内存块用于整个对象以及复合对象),而且可能效率也是最好的。当您需要合成时,请使用此解决方案
为什么作文不适合这个问题
组成意味着一些共识:
- 合成对象本身并不存在
- 它们与复合对象的关联在该对象的生存期内是永久的
- 顶点数组(独立)
- 边缘阵列
您甚至可以使用数组索引而不是指针作为替代(这确实有它的用途,例如,如果您想使用后一个数组作为三维渲染的索引缓冲区)。这一切都取决于你的需要。这是谁拥有指针的问题。如果您的Edge类拥有它们,那么您可以使用auto_ptr。但是,您可以说您的顶点对象是在堆栈上分配的,因此在这种情况下不需要显式清理,因为当它们超出范围时将被删除。一般来说,智能指针是“智能的”,因为它们处理所涉及的所有权问题。在上面,您希望谁拥有这些顶点?使用普通指针。如果在堆栈上分配指向的对象,那么智能指针就没有多大帮助
如果您长期关心安全性和边界检查等问题,请根据每个
顶点的id对其进行排序(例如,Decise0这是通常的权衡:智能指针会更安全,但速度较慢。如果您想这样做,请使用
对于“业务逻辑”,我强烈主张使用智能指针。但看起来您可能正在进行CPU密集型图形处理,这是速度可能是一个重要因素的情况之一。因此,我建议:
//typedef Vertex *VertexPtr
typedef shared_ptr<Vertex> VertexPtr
class Edge {
int id;
VertexPtr source;
VertexPtr target;
};
//typedef顶点*VertexPtr
typedef共享\u ptr VertexPtr
阶级边缘{
int-id;
VertexPtr源;
VertexPtr靶;
};
使用此功能进行调试,并在一切正常时切换/
,以提高速度
注意:如果顶点有可能指向指向它的边,事情会变得更复杂——你需要对其中一个指针使用弱\u ptr
,以避免循环引用。你希望“智能指针”做什么?你希望顶点的“列表”中有多少顶点“堆栈已分配”?您肯定不是在谈论std::list
吗?您是在使用某种自定义alloca()
-基于分配器?听起来很可怕…列表代表任何容器,还没有决定哪一个是最好的。堆栈分配,因为顶点不是用新的创建的。在所有智能指针中,为什么要共享?当你想要严格的所有权时为什么要引入引用计数…?@j_random_hacker:智能指针不是本质的“更安全"--这取决于你如何使用它们。不同的智能指针封装了不同的所有权语义——你应该在你想要的语义出现时使用它们,而不仅仅是因为有人告诉你智能指针很棒。它们非常有用,但你不应该盲目地应用它们。另外,在顶点*
和共享\u ptr
使用typedef不是一个好主意——它们具有不同的语义,两者之间的切换会导致事情以意外的方式中断。这里最好的方法是顶点不属于任何边。有一个顶点集合拥有顶点,还有一个边集合引用到顶点。不需要智能指针。@Stuart:当然“这取决于你如何使用它们”。你为什么认为shared_ptr的所有权语义在这里不合适?一个顶点将由多条边共享。我同意typedef
很弱,因为它不足够
//typedef Vertex *VertexPtr
typedef shared_ptr<Vertex> VertexPtr
class Edge {
int id;
VertexPtr source;
VertexPtr target;
};