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来管理对象指针的生命期,好吧,也许这样会遭到大师的批评,球指教!