Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c+中的合成+;使用原始指针还是智能指针?_C++_Oop_Smart Pointers_Composition - Fatal编程技术网

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;
};
这种方法在内存使用方面是最好的(一个内存块用于整个对象以及复合对象),而且可能效率也是最好的。当您需要合成时,请使用此解决方案

为什么作文不适合这个问题
组成意味着一些共识:

  • 合成对象本身并不存在
  • 它们与复合对象的关联在该对象的生存期内是永久的
在数据模型中,您有单独的:

  • 顶点数组(独立)
  • 边缘阵列
两者都可能是堆栈分配的(但这并不重要)

然后希望每条边引用N个顶点

边缘并不拥有它们——它只是指它们。因此,无论是合成还是智能指针(旨在引入某种所有权关联)都不是您想要的,因为设计表明顶点由顶点数组而不是边所拥有

因此,选择一个普通指针


您甚至可以使用数组索引而不是指针作为替代(这确实有它的用途,例如,如果您想使用后一个数组作为三维渲染的索引缓冲区)。这一切都取决于你的需要。

这是谁拥有指针的问题。如果您的Edge类拥有它们,那么您可以使用auto_ptr。但是,您可以说您的顶点对象是在堆栈上分配的,因此在这种情况下不需要显式清理,因为当它们超出范围时将被删除。

一般来说,智能指针是“智能的”,因为它们处理所涉及的所有权问题。在上面,您希望谁拥有这些顶点?

使用普通指针。如果在堆栈上分配指向的对象,那么智能指针就没有多大帮助


如果您长期关心安全性和边界检查等问题,请根据每个
顶点的id对其进行排序(例如,Decise
0这是通常的权衡:智能指针会更安全,但速度较慢。如果您想这样做,请使用

对于“业务逻辑”,我强烈主张使用智能指针。但看起来您可能正在进行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;
};