在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);
声明字段时,如何判断是否应使用指针或常规变量?
答案 0 :(得分:6)
您可能希望在以下情况下使用指针:
您可能还想使用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 ++也不这样做。