现在的位置: 首页 > 综合 > 正文

返回引用很危险

2013年05月29日 ⁄ 综合 ⁄ 共 1532字 ⁄ 字号 评论关闭

Meters大师说的很对,如果你通过memfun将private mem以引用或者指针形式暴漏出去,那么会有承担private mem变为public的风险,也就是说其他调用可以不经你允许类里面的private mem,当然这破坏你class应有的封装性,好吧,光说不练假把式,代码说明了问题:

#include <iostream>
#include <boost/shared_ptr.hpp>
using namespace std;

class Point
{
public:
	Point(){}
	Point(int x, int y):m_X(x),m_Y(y)
	{
	}
	int GetX()const
	{
		return m_X;
	}
	int GetY()const
	{
		return m_Y;
	}
	void setX(int newVal)
	{
		m_X = newVal;
	}
	void setY(int newVal)
	{
		m_Y = newVal;
	}
private:
	int m_X;
	int m_Y;
	
};

struct RectData
{
	RectData(){}
	RectData(Point &a1,Point &a2)
	{
		ulhc = a1;
		lrhc = a2;
	}
	Point ulhc;
	Point lrhc;
};

class Rectangle 
{
public:
	Rectangle(RectData& aData)
	{
		m_pData = boost::shared_ptr<RectData>(new RectData(aData));
	}
	const Point& GetUpperLeft()const
	{
		return m_pData->ulhc;
	}
	const Point& GetLowerRigth()const
	{
		return m_pData->lrhc;
	}

private:
	boost::shared_ptr<RectData> m_pData;
};

class GuiObject
{
public:
	GuiObject(Rectangle &aRect):m_Rect(aRect){}
	Rectangle GetRect()const
	{
		return m_Rect;
	}
private:
	Rectangle m_Rect;
};
const Rectangle BoundingBox(const GuiObject& aObj)
{
	return aObj.GetRect();
}

int main()
{
	Point lp1(1,2),lp2(3,4);
	RectData lRect;
	lRect.lrhc = lp1;
	lRect.ulhc = lp2;
	Rectangle lRectangle(lRect);
	boost::shared_ptr<GuiObject> lpGUI(new GuiObject(lRectangle));
	Point* lpUpperLeft = const_cast<Point*>(&(BoundingBox(*lpGUI).GetUpperLeft()));
	cout << "Origin Data:\n x:" << lpUpperLeft->GetX() << " y:" << lpUpperLeft->GetY() << endl;
	lpUpperLeft->setX(-1);
	lpUpperLeft->setY(-2);
	cout << "After Changed:\n x: " << lpGUI->GetRect().GetUpperLeft().GetX() << " y:"
		<< lpGUI->GetRect().GetUpperLeft().GetY() << endl;
}

运行下,你就知道,不好,被无情地修改啦!PS:这个代码没有meyers所说的悬空指针的问题,因为boost:shared_ptr来管理对象指针的生命期,好吧,也许这样会遭到大师的批评,球指教!微笑

抱歉!评论已关闭.