摘要:返回内部变量的指针是危险的,尽量不要这样做。
返回内部变量指针的例子
// class for representing points
class Point {
public:
Point(int x, int y);
...
void setX(int newVal);
void setY(int newVal);
...
};
struct RectData { // Point data for a Rectangle
Point ulhc; // ulhc = " upper left-hand corner"
Point lrhc; // lrhc = " lower right-hand corner"
};
class Rectangle {
...
private:
std::tr1::shared_ptr<RectData> pData;// see Item 13 for info on tr1::shared_ptr
};trick: 为了保证对象 Rectangle 对象尽可能的小,将需要的数据保存在外部的变量中。另外:对于自定义的数据类型(Point),传递指针比传值更加的高效,所以定义了如下的函数:
class Rectangle {
public:
...
Point& upperLeft() const { return pData->ulhc; }
Point& lowerRight() const { return pData->lrhc; }
...
};以上代码会造成Point 对象修改!有两点需要注意。
Point coord1(0, 0);
Point coord2(100, 100);
const Rectangle rec(coord1, coord2); // rec is a const rectangle from
// (0, 0) to (100, 100)
rec.upperLeft().setX(50); // now rec goes from
// (50, 0) to (100, 100)!解决方式为:给返回的引用机上const 限制。
class Rectangle {
public:
...
const Point& upperLeft() const { return pData->ulhc; }
const Point& lowerRight() const { return pData->lrhc; }
...
};尽管有const 的加持,返回内部变量的指针,会造成“野指针”的问题。比如以下的例子
class GUIObject {... };
// value; see Item 3 for why return type is const
const Rectangle boundingBox(const GUIObject& obj);
GUIObject *pgo; // make pgo point to some GUIObject
...
// get a ptr to the upperleft point of its
const Point *pUpperLeft = &(boundingBox(*pgo).upperLeft());
// bounding box当调用boundingBox 函数时,会产生临时的变量tmp,且把临时变量的upperLeft 变量的地址,赋值给了pUpperLeft 变量,当离开该语句时,tmp 变量被销毁,此时的pUpperLeft 就成为了“野指针”。
总结:
尽量的避免返回内部变量的句柄!