【问题标题】:What are some of the disadvantages of using a reference instead of a pointer?使用引用而不是指针有哪些缺点?
【发布时间】:2011-11-09 20:16:34
【问题描述】:

假设“A”类存在并且是正确的。使用对“A”的引用而不是类“B”中的指针会产生什么负面结果。那就是:

// In Declaration File
class A;

class B
{
public:
   B();
   ~B();
private:
    A& a;
};

// In Definition File
B::B(): a(* new A())
{}

B::~B()
{
    delete &a;
}

为了“B”的进一步正确性而省略了额外的代码,例如复制构造函数和赋值运算符,只是为了演示问题的概念。

【问题讨论】:

  • 有趣。我以前见过这样的代码。可能是,这只是一种避免取消引用和使用-> 并且仍然使a 动态分配的方法,出于某种原因:?为问题 +1。
  • 这有什么意义,而不仅仅是A a;?这不是比引用或指针更好吗?
  • @tenfour 在很多情况下,但这是一个简化的示例 - 假设 a 背后的值是由工厂创建的。
  • @tenfour 同样使用值对象可以防止前向声明。
  • new 获得的解引用指针初始化引用不是惯用的 C++。

标签: c++ pointers coding-style reference


【解决方案1】:

直接的限制是:

  • 您不能更改引用的值。您可以更改它所指的A,但您不能在B 的生命周期内重新分配或重新分配a
  • a 绝不能是 0

因此:

  • 对象不可分配。
  • B 不应该是可复制构造的,除非您教 A 及其子类型正确克隆。
  • 如果存储为值,B 将不适合作为集合类型的元素。 Bs 的向量可能最容易实现为 std::vector<B*>,这可能会引入进一步的复杂性(或简化,具体取决于您的设计)。

根据您的需要,这些可能是好事。

注意事项:

  • 切片是另一个需要注意的问题如果a 是可分配的,并且分配在B 内是可访问的。

【讨论】:

  • +1 表示“这些可能是好事”......这就是我认为的(假设它们适用)。在可能的情况下使用引用而不是指针记录了它不为空且不会更改的事实......在尝试理解其他人的代码时非常有用的信息。
  • 已编辑以反映缺少的代码是复制构造函数和赋值运算符。
  • 第一个“缺点”是非常非常好的事情,而第二个只是扩展了它。 B 将不再可分配也很好,因为它比 B 以损坏的方式分配要好。
  • @timday:它也阻止了你引入动态对象生命周期的错误......在某种程度上。
  • 对于一些问题来说绝对是一件好事。我使用它的一个常见用途是在移动引用计数对象时(在这种情况下,A 是引用计数类型,B 只是一个包含引用的容器)。
【解决方案2】:

您不能在事后更改 a 引用的对象,例如在任务中。此外,它使您的类型成为非 POD(无论如何,由于私有数据成员,给定的类型无论如何都是非 POD,但在某些情况下它可能很重要)。

但主要的缺点可能是它可能会使您的代码的读者感到困惑。

【讨论】:

    【解决方案3】:

    当然,通过在你的类中添加引用成员B意味着编译器不能再生成隐式的默认构造函数和复制构造函数,以及赋值运算符;并且手动编写的赋值运算符都不能重新分配a

    我认为没有负面结果,除了 delete &a 可能看起来很奇怪。对象是由new 创建的这一事实通过将结果绑定到一个引用而有些丢失,这可能只是因为它的生命周期必须由B 控制这一事实尚不清楚。

    【讨论】:

      【解决方案4】:

      如果您使用参考:

      • 您必须在施工时提供价值
      • 你不能改变它所指的东西
      • 不能为空
      • 它会阻止你的班级被分配

      您可能会考虑使用某种智能指针(std::unique_ptr、std::shared_ptr 等)。这具有自动为您删除对象的额外好处。

      【讨论】:

        【解决方案5】:

        对动态分配对象的引用违反了最小意外原则;也就是说,通常没有人期望像您那样编写代码。总的来说,这将使未来的维护成本更高。

        【讨论】:

          【解决方案6】:

          引用的问题在于,它看起来像同一个变量的别名或其他名称,但如果您查看内部生成的机器代码,它们使用常量指针来执行操作,这可能是一个性能问题,因为您可能会假设在变量算术正在发生的代码,但在汇编代码级别,它们正在操作您在代码级别可能无法实现的指针。 您可能不想在需要快速整数或浮点运算的地方使用指针操作。

          【讨论】:

            猜你喜欢
            • 2013-02-09
            • 1970-01-01
            • 1970-01-01
            • 2011-06-17
            • 2013-02-17
            • 1970-01-01
            • 1970-01-01
            • 2010-10-13
            相关资源
            最近更新 更多