我如何决定是否应该使用指针或常规变量?

时间:2013-04-18 17:44:31

标签: c++

在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);

声明字段时,如何判断是否应使用指针或常规变量?

3 个答案:

答案 0 :(得分:6)

您可能希望在以下情况下使用指针:

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

您可能还想使用smart pointer

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

答案 1 :(得分:4)

常规变量如果

  • Foo是该课程不可或缺的一部分,即每个实例都有自己的Foo
  • Foo不是太大(它可以放在堆栈上)。

指针如果

  • 多个实例可能共享一个Foo
  • 某些情况下某些情况可能没有Foo
  • Foo非常大,应始终在堆上。

答案 2 :(得分:0)

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

复杂性需要证明是合理的,在这个例子中,你没有表明任何理由在指针示例中出现额外的复杂性,所以你应该使用自动变量。

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

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

此外,C#和Java更多地依赖于多态类型,并且他们没有C ++所拥有的“不支付你不使用的东西”。多态类型需要指针,但C#和Java很乐意让你支付成本,即使你不需要,而C ++也不这样做。