在阅读了一些教程之后,我得出的结论是应该始终使用对象指针。但是在阅读QT教程时(http://zetcode.com/gui/qt4/painting/),我也看到了一些例外情况,其中QPaint对象是在堆栈上创建的。所以现在我很困惑,什么时候应该使用指针?
在阅读了一些教程之后,我得出的结论是应该始终使用对象指针。但是在阅读QT教程时(http://zetcode.com/gui/qt4/painting/),我也看到了一些例外情况,其中QPaint对象是在堆栈上创建的。所以现在我很困惑,什么时候应该使用指针?
如果您不知道何时应该使用指针,那就不要使用它们。
当您需要使用指针时,情况会变得明显,每种情况都是不同的。很难简洁地总结何时应该使用它们。不要养成“始终为对象使用指针”的习惯,这肯定是错误的建议。
使用指针的主要原因:
我不清楚你的问题是关于指向对象 vs 基于栈的对象,还是指向对象 vs 对象引用。也有一些用途不属于这两个范畴。
关于基于栈 vs 指针,似乎上面已经涉及到了。有几个原因,其中最明显的是对象的生存期。
关于引用 vs 指针,请尽可能使用引用,但有些事情只能使用指针,例如(有许多用途):
最重要的是,指针(和引用,与自动/基于栈和静态对象相反)支持多态性。基类的指针实际上可以指向派生类。这是C++中支持面向对象行为的基本特征。
首先,这个问题是错误的:困境不在于指针和栈之间,而在于堆和栈之间。您可以在栈上拥有一个对象并传递该对象的指针。我假设您真正想问的是应该声明类的指针还是类的实例。
答案取决于您想要对该对象执行什么操作。如果控制离开函数后对象必须存在,则必须使用指针并在堆上创建对象。例如,当您的函数必须返回指向创建的对象的指针或将对象添加到在调用函数之前创建的列表中时,您将执行此操作。
另一方面,如果对象局限于函数本身,则最好在栈上使用它。这使编译器能够在控制离开函数时调用析构函数。
class Person {
public:
string name; // NOT string * name;
...
};
void f() {
string value; // NOT string * value
// use vvalue
}
在以下场景中,您通常需要使用指针:
您需要一个包含不同类对象的集合(大多数情况下它们将具有共同的基类)。
您需要一个栈分配的对象集合,如果太大就可能导致堆栈溢出。
您需要能够快速重新排列对象的数据结构 - 如链接列表、树形结构或类似物。
您需要一些复杂的对象生命周期管理逻辑。
您需要一种数据结构,允许从一个对象直接导航到另一个对象 - 如链接列表、树形结构或任何其他图形。
除了其他人提到的点(特别是关于控制对象生命周期的),如果您需要处理NULL对象,则应使用指针而不是引用。虽然可以通过类型转换创建NULL引用,但通常这是一个不好的想法。
在这种情况下,我实际上使用指针:
class Foo
{
Bar* bar;
Foo(Bar& bar) : bar(&bar) { }
Bar& Bar() const { return *bar; }
};
使用指针涉及到两个正交的事情:
动态分配。通常情况下,当对象的生命周期超出创建它的作用域时,应该进行动态分配。这样的对象是一种资源,其所有者必须明确指定(通常是某种智能指针)。
通过地址访问(无论对象是如何创建的)。在这种情况下,指针并不意味着所有权。这种访问可能需要在以下情况下进行:
#1和#2可以以不同的配置出现,例如您可以想象通过指针访问动态分配的对象,但是这样的对象也可以通过引用传递给某个函数。您还可以获得指向堆栈上创建的某个对象的指针等。
对于大部分的代码,使用可良好复制对象的按值传递是正确的方法。
如果速度真的很重要,可以在可能的情况下使用按引用传递,最后再考虑使用指针。