关于传递对象的C ++约定(指针与引用)

时间:2018-03-25 12:10:54

标签: c++ pointers reference conventions

我想制定关于将参数传递给函数/方法的约定。我知道这是一个常见的问题而且它已被多次回答,但我搜索了很多,并没有发现任何完全满足我的东西。

价值传递是显而易见的,我不会提到这一点。我想出的是:

  1. 通过非const引用表示,该对象为已修改
  2. 传递 const引用表示该对象已使用
  3. 通过指针传递意味着对象的引用将是 STORED 。是否通过所有权取决于具体情况。
  4. 它似乎是一致的,但是当我想选择堆分配的对象并将其传递给2. case参数时,它看起来像这样:

    void use(const Object &object) { ... }
    
    //...
    
    Object *obj = getOrCreateObject();
    use(*obj);
    

    Object &obj = *getOrCreateObject();
    use(obj);
    

    我看起来都很奇怪。你会提出什么建议?

    PS我知道应该避免使用原始指针并使用智能(更简单的内存管理和所有权表达),这可能是重构我工作项目的下一步。

3 个答案:

答案 0 :(得分:1)

如果您愿意,可以使用这些约定。但请记住,在处理其他人编写的代码时,您不能采用约定。您也不能假设阅读代码的人知道您的约定。当条件可能不明确时,您应该记录带有注释的界面。

  

通过指针传递意味着该对象将被存储。谁的拥有者将取决于具体情况。

我只能想到一个指针参数的所有权应该传递给被调用者的上下文:智能指针的构造函数。

除了可能的存储意图之外,指针参数可以替代地具有与引用参数相同的含义,并且参数是可选的。您通常不能使用引用表示可选参数,因为它们不能为null - 尽管使用自定义类型您可以使用对sentinel值的引用。

  

我看起来都很奇怪。你会提出什么建议?

对我来说都不奇怪,所以我的建议是习惯了。

答案 1 :(得分:0)

在我的观点中,它们是相同的。在帖子的第一部分,您正在谈论签名,但您的示例是关于函数调用。

答案 2 :(得分:0)

您的约定的主要问题是您不会考虑与代码接口的可能性(例如,由其他人编写),但不遵守您的惯例。

一般来说,我使用一组不同的约定,很少发现需要解决它们。 (主要的例外是如果需要使用指针指针,但我很少需要直接这样做。)

如果以下任何一项可能属实,则通过非const引用是合适的;

  • 可以更改对象;
  • 该对象可以通过非const引用传递给另一个函数[与选择省略const的开发人员使用第三方代码时相关 - 这实际上是许多初学者或懒惰的开发人员做的;;
  • 对象可以通过非const指针传递给另一个函数[当使用第三方代码时相关的是选择省略const的开发人员,或使用旧版API时);
  • 调用对象的非const成员函数(无论它们是否更改对象)[通常考虑使用第三方代码时,开发人员希望避免使用{{1} }]。

相反,如果满足以下所有条件,则可以传递const个引用;

  • 没有更改对象的非const成员;
  • 该对象仅通过mutable引用,const指针或值传递给其他函数;
  • 只调用该对象的const个成员函数(即使这些成员能够更改const个成员。

在函数复制对象的情况下,我将按值而不是mutable引用传递。 (例如,我不会通过const引用,然后在函数中构造传递对象的副本。)

传递非const指针是相关的,如果它适合传递非const引用,但也有可能不传递任何对象(例如const)。< / p>

传递nullptr指针是相关的,如果它适合传递const引用,但也有可能不传递任何对象(例如const)。

我不会更改以下任何一种

的约定
  • 在函数中存储对象的引用或指针供以后使用 - 可以将指针转换为引用,反之亦然。并且可以存储任何一个(可以指定指针,可以使用引用来构造对象);
  • 区分动态分配的对象和其他对象 - 因为我大多要么完全避免使用动态内存分配(例如使用标准容器,通过引用传递它们或者简单地从它们周围传递迭代器)或者 - 如果我必须使用{直接{1}}表达式 - 将指针存储在另一个负责释放的对象中(例如nullptr),然后传递包含的对象。