2010-01-20 34 views
3

解引用指针会使代码非常难以阅读。我通常所做的就是引用指向对象并使用引用。例如:对指向对象的引用

shared_ptr<std::vector<int> > sp = get_sp_to_vector(); 
std::vector<int>& vec = *sp; 
... 
vec.push_back(5); 

我不知道这是否是一种好的做法。它有什么缺点吗?

更新:要完成这个例子,我定义get_sp_to_vector()方式如下:

shared_ptr<std::vector<int> > get_sp_to_vector() 
{ 
    // create a vector and send back a shared pointer pointing at it 
    shared_ptr<std::vector<int> > sp(new std::vector<int>); 
    sp->push_back(1); sp->push_back(3); 
    return sp; 
} 
+2

我也是这样。对我来说这似乎很合理,当我有某种指针时,但我真正想与之合作的是它指向的东西。为避免不同类型变量之间的名称冲突引用相同范围内的相同值,我使用名称,如“foo”作为引用或实际对象,“p_foo”作为指针,“ap_foo”作为std :: auto_ptr '和'sp_foo'作为'boost :: shared_ptr'或'std :: tr1 :: shared_ptr'。 – Wyzard 2010-01-20 03:32:23

+0

似乎最近有一种趋势回答评论中的问题......一束紫罗兰。男人起来。如果可能的话,我会投票评论这一评论 - 不是因为我认为答案不好,而是因为这是一个答案,因此不是*评论*。 – paxos1977 2010-01-20 03:55:51

+1

@ceretullis:不,我的评论没有解决它是否有任何缺点的问题。这就是为什么我选择写评论而不是答案。 – Wyzard 2010-01-20 03:59:09

回答

2

使用局部引用是很常见的,特别是在循环体内部,但是有一个要求:只有当引用明显地和目标对象一样长时才会这样做。

这通常是不难保证,但这里有一些不好的例子:

shared_ptr<X> p = get_p(); 
X& r = *p; 
p.reset(); // might result in destroying r 
use(r); // oops 

// or: 
shared_ptr<X> p = get_p(); 
X& r = *p; 
p = get_some_other_p(); // might result in destroying r 
use(r); // oops 
+0

shared_ptr没有release()函数,只是reset(),但我同意这一点 - 将两个变量耦合在一起会增加复杂性的非零开销。由于其中一个是参考,所以甚至不能更新r以匹配p的新值。 – 2010-01-20 04:51:52

+0

哎呀,谢谢,因为你认识到这个意图是重要的。 – 2010-01-20 05:07:23

2

我不认为这是一个很好的做法。指针是C/C++开发和B/C的主要支持,C/C++编码人员对指针所需的去引用语法感到满意。尽可能避免使用指针(尽管不是出于语法原因),但有时它只是这项工作的最佳工具。如果你的代码是粗糙的b/c你使用的是指针,我通常会将它引用到一个函数中,该函数通过引用传递对象,基本上你做了你正在做的事情,但在我看来,它是这样做的一个更优雅的方式。因此,而不是:

shared_ptr<std::vector<int> > sp = get_sp_to_vector(); 
std::vector<int>& vec = *sp; 
...ugly stuff... 
vec.push_back(5); 

我会做:

void func(std::vector<int> &vec) 
{ 
    ... previously ugly stuff... 
    vec.push_back(5); 
} 

shared_ptr<std::vector<int> > sp = get_sp_to_vector(); 
func(*sp); 

编辑:
这并不是说,你应该创建一个功能就是要为指针优雅的语法,因为它是声明如果你不喜欢指针语法,并且你的代码使用干净而简洁的函数,那么你可以简单地使这些函数在调用函数时接受引用并取消引用你的指针。对于只有少量调用* p或p-> x的情况,创建带引用的函数或创建引用来调用p.x似乎很愚蠢。在这些情况下只需使用指针语法,因为这是C/C++语法。

其他人已经提出在循环内使用引用,其中指针可能必须被多次取消引用。我确实同意,在这些情况下,参考将是有益的。

+3

@RC:你正在做同样的事情......只是把它隐藏在一个函数调用中(这取决于将要完成的操作是合适的)。 – paxos1977 2010-01-20 03:46:59

+0

是的,我在回答中说过。我发现将一个取消引用的指针作为参考传递给函数,而在相同的代码块中创建不同的引用。我并不是说我会写一个函数来简单地让代码在语法上看起来不同。我的观点是,如果你不喜欢指针,不要将它们作为指针传递给函数调用。 – 2010-01-20 03:54:12

+0

@RC:好的... +1,我买了,但是在你的回答中不明确。看起来,也许我只是密集的,你建议Jabba做抽取方法类型重构只是为了隐藏参考的创建。 – paxos1977 2010-01-20 04:14:18

2

恕我直言,我认为这是一个可以接受的做法(有一些注意事项 - 参见Roger Pate's后)。如果你只是为push_back()调用添加一行代码,那么我认为这是不可接受的。然而,如果你发现你正在引用指针许多时间,那么它不仅可以将其一次引用到引用对象中,而且还可以是性能优势(取决于你的编译器,有问题的代码,月亮的阶段等)。

+0

+1在指针经常被取消引用的情况下提供了很好的用法。我不知道当编译器检测到指针被去引用的循环时,它可以为你做这种优化吗?似乎它需要/想知道循环执行多少次才能知道它是否有益。 – 2010-01-20 04:33:04

+2

实际上,将指针取消引用到引用中几乎不会对每个编译器的性能产生任何影响。在引擎盖下,引用基本上以与指针相同的方式实现。 – 2010-01-20 04:46:03

+0

同意特里马哈菲。但是,使用对数组中特定条目的引用可能会节省重复的添加。 – rlbond 2010-01-20 05:01:35

1

如果我真的在做指针操作,那么我会留下一个指针。 如果我的指针仅仅是一个可用的引用,那么我会留下一个指针。 如果我确信或者想要确保指针总是非零 (即,如果我正在从方法中返回非零对象),那么我通过使用引用来明确这一点。

1

工作从您的推荐码回来,我不同意:

shared_ptr<std::vector<int> > sp = get_sp_to_vector(); 
... 
sp->push_back(5); 

是“非常难读”。它也比你的代码短。所以虽然我认为定义和使用本地引用没有太大的错误,但我也不认为你应该规定永远这样做。

也许如果你的指针代码很难阅读,那是因为你错过了一些可以使它更简单的技巧。也许如果你用一个不好的指针代码的例子问你另一个问题,你现在用一个引用来解决这个问题,SOers会找到其他的修正。