我如何决定是使用指针还是常规变量
How do I decide if I should use a pointer or a regular variable?
在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);
在声明字段时,如何决定应该使用指针还是常规变量?
如果:
- 被引用的对象可以比父对象存活时间长。
- 由于大小的原因,您希望确保引用的对象在堆上。
- 指针是从类外部提供的。
- Null是可能的值
- 该字段可以动态设置为不同的对象。
- 实际的对象类型在运行时确定。例如,该字段可以是一个基类指针,指向多个子类中的任何一个。
你也可以使用智能指针。
上面的最后一点适用于示例代码。如果你的字段是Foo类型的,并且你给它分配了一个FieldImpl,剩下的就是FieldImpl的Foo部分。这被称为切片问题。
常规变量 if
-
Foo
是类不可分割的一部分,即每个实例总是有自己的Foo
和 -
Foo
不是太大(它可以放在堆栈上)。
指针/strong>如果
- 多个实例可以共享单个
Foo
, - 在某些情况下可能没有
Foo
, 或 -
Foo
真的很大,应该一直在堆上。
c++在设计时就考虑了自动变量。像RAII这样关键的c++习惯用法依赖于自动变量。由于c++的设计决策,使用自动变量比使用指针更简单、更容易。除非确实需要指针提供的功能,否则不应该增加使用指针的复杂性。(如果你必须使用智能指针)
复杂性需要被证明是合理的,在这个例子中,你没有说明指针例子中额外复杂性的任何原因,所以你应该使用一个自动变量。
在使用了10年的c#和Java之后,指针很简单,而常规变量对我来说很复杂:)所以应该有更严重的理由不使用指针。例如,我猜指针不是处理器缓存友好的
c#和Java的设计与c++不同。它们的语法和运行时旨在使指针成为更简单的(或唯一的)方法,并且它们会处理在幕后为您创建的一些问题。试图绕过语言来避免Java和c#中的指针会增加复杂性。
此外,c#和Java在很大程度上依赖于多态类型,并且它们没有c++所具有的"不为不使用的东西付费"的策略。多态类型需要指针,但c#和Java很乐意让你付出代价,即使你不需要,而c++不这样做。
相关文章:
- 指针变量在 cout 函数中不起作用
- 如何将指针变量作为引用参数传递?
- 有没有办法在同名类 (c++) 中为对象分配一个指针变量
- 我试图了解在异或操作后指针变量正在更改
- 调用带有指针对象错误的指针变量
- 如何在 cuda 中将结构的指针变量从主机复制到设备
- 非指针变量和类成员上的新放置
- 线路抑制状态错误 C4703 可能未初始化的局部指针变量"back"已使用
- 全局外部指针变量在 DLL 中不可见
- 如何访问在 c++ 中在类内声明的结构类型指针变量?
- C++ 中指针变量的内存释放
- 使用指针变量打印特定的数组变量
- 如何使用构造函数初始化内存地址(指针变量)?
- 如何释放为指针变量本身提供的内存?
- 如果地址已知,如何获取指针变量的名称
- 如何处理参数中的基类和指针变量
- 指针变量 在数组中定位零
- 隐式指针变量,在自动定义中具有另一个指针变量
- 为什么可以将Char指针变量初始化为字符串,而INT指针变量不能初始化到整数数组
- 错误 C4703 可能未初始化的局部指针变量'y'使用