1

在 C++ 中,我可以将字段声明为某种类型的常规变量,在构造函数中实例化它,然后再使用它:

private:    Foo field;
...

A::A() {
    // upd: likely i instatiate field wrong ways (see comments)
    field = FieldImpl();
}
....
method(field);

或者,我可以使用指针:

private:    Foo* field;
...

A::A() {
    field = new FieldImpl();
}

A::~A() {
    delete field;
}

...
method(*field);

声明字段时,如何决定是使用指针还是常规变量?

4

3 回答 3

6

在以下情况下,您可能需要使用指针:

  • 被引用的对象可以比父对象更长寿。
  • 由于大小,您要确保引用的对象在堆上。
  • 指针是从类外部提供的。
  • Null 是一个可能的值。
  • 该字段可以动态设置为不同的对象。
  • 实际的对象类型是在运行时确定的。例如,该字段可能是指向多个子类中的任何一个的基类指针。

您可能还想使用智能指针

上面的最后一点适用于您的示例代码。如果您的字段是 Foo 类型,并且您为其分配了一个 FieldImpl,那么剩下的就是 FieldImpl 的 Foo 部分。这被称为切片问题

于 2013-04-18T17:48:07.887 回答
4

正则变量if

  • Foo是类的一个组成部分,即每个实例总是有自己Foo
  • Foo不是太大(它可以放在堆栈上)。

指针如果

  • 几个实例可能共享一个Foo
  • 可能有些实例Foo在某些时候没有,或者
  • Foo真的很大,应该总是在堆上。
于 2013-04-18T17:50:48.213 回答
0

C++ 在设计时考虑了自动变量。像 RAII 这样的关键 C++ 习语依赖于自动变量。由于 C++ 的设计决策,使用自动变量比使用指针更简单、更容易。除非您确实需要它们提供的功能,否则不应增加使用指针的复杂性。(如果你必须使用智能指针。)

需要证明复杂性是合理的,在此示例中,您没有显示指针示例中额外复杂性的任何原因,因此您应该使用自动变量。

经过 10 年的 C# 和 Java 指针很简单,而常规变量对我来说很复杂 :) 所以应该有更多不使用指针的原因。例如,我猜指针不是处理器缓存

C# 和 Java 的设计与 C++ 不同。它们的语法和运行时旨在使指针成为更简单(或唯一)的方法,并且它们会处理在幕后为您创建的一些问题。试图绕过该语言以避免 Java 和 C# 中的指针会增加复杂性。

此外,C# 和 Java 在更大程度上依赖于多态类型,并且它们没有 C++ 所具有的“不为不使用的东西付费”的政策。多态类型需要指针,但 C# 和 Java 很乐意让您付出代价,即使您不需要,而 C++ 不这样做。

于 2013-04-18T17:47:59.017 回答