【发布时间】:2015-05-04 13:38:30
【问题描述】:
我从来没有使用过任何类型的智能指针,但是当主题是指针时,我几乎到处都在阅读它们。我确实理解在某些情况下,智能指针比原始指针更好用,因为在某种程度上它们管理指针的所有权。但是,我仍然不知道,“我不需要智能指针”和“这是智能指针的情况”之间的界限在哪里。
比方说,我有以下情况:
class A {
public:
double get1(){return 1;}
double get2(){return 2;}
};
class SomeUtilityClass {
public:
SomeUtilityClass(A* a) : a(a) {}
double getResult(){return a->get1() + a->get2();}
void setA(A* a){a = a;}
private:
A* a;
};
int main(int argc, char** argv) {
A a;
SomeUtilityClass u(&a);
std::cout << u.getResult() << std::endl;
A a2;
u.setA(&a2);
std::cout << u.getResult() << std::endl;
return 0;
}
这当然是一个过于简单的例子。我的意思是SomeUtilityClass 不应该“拥有”A 的实例(因为它只是一个实用程序类),因此它只包含一个指针。
关于指针,我知道的唯一可能出错的是:
-
SomeUtilityClass可以用空指针实例化 - 指向的对象可能被删除/超出范围,
SomeUtilityClass没有注意到它
智能指针如何帮助避免这个问题?在这种情况下使用智能指针还能获得哪些其他好处?
PS:我知道有几个关于智能指针的问题(例如this one)。但是,如果您能告诉我对这个特定示例的影响,我将不胜感激。
【问题讨论】:
-
原始指针完美地捕获了对具有范围生命周期的数据的非拥有引用的概念。你不应该在这里使用智能指针。
-
如果您在野外使用
new,这是一个非常强烈的提示,您可能需要一个智能指针。如果您使用new [],这是一个非常强烈的提示,您可能需要std::vector或其他容器。 -
如果
nullptr没有意义,您可以考虑参考或std::reference_wrapper。 -
顺便说一句:难道
void setA(A* a){a = a;}没有做你想做的事吗?我有时会在成员前面加上“m”;它既可以作为阅读代码时的指示符,也可以作为将成员与其他名称区分开来的自然“命名空间”。在 C# 中,它可能是一个下划线。 -
如果你想确保指针至少在类的生命周期内是活动的,你应该使用共享指针
标签: c++ pointers smart-pointers