initializeContainer()
根本不具有訪問通過正常渠道來設置Container::mItem
構件。並且您不能使用Container::getItem()
來提供該訪問權限,因爲它返回指向mItem
的指針,並且您無法從該指針到達mItem
。
您需要更改Container
允許訪問mItem
,無論是通過:
給Container
,設置mItem
一個公共方法,然後讓initializeContainer()
調用方法:
class Container {
private:
std::auto_ptr<MyItem> mItem;
public:
MyItem* getItem() { return mItem.get(); }
void setItem(const MyItem &item) { mItem.reset(new MyItem(item)); }
};
void initialize(Container& container) {
MyItem item;
container.setItem(item);
}
聲明initializeContainer()
作爲friend
的Container
所以它可以直接訪問private
成員:
class Container {
private:
std::auto_ptr<MyItem> mItem;
public:
MyItem* getItem() { return mItem.get(); }
friend void initialize(Container&);
};
void initialize(Container& container) {
container.mItem.reset(new MyItem);
}
擺脫initializeContainer()
乾脆給Container
公共初始化方法代替:
class Container {
private:
std::auto_ptr<MyItem> mItem;
public:
void init() { mItem.reset(new MyItem); }
MyItem* getItem() { return mItem.get(); }
};
Container c;
c.init();
是否有通過指針處理中的字段的習慣的方法?
不是你試圖去做的方式,沒有。您正在嘗試使用與該對象本身不相關的指針,該對象本身就是由它所持有的。因此,您不能使用該指針訪問Container
對象的成員,因爲它不指向開頭的Container
對象。
我也不允許更改Container的接口。
那麼,你是運氣不好,因爲你試圖做的事情需要一個界面的變化。除非你用一個醜陋的指針砍,如:
class Container {
private:
std::auto_ptr<MyItem> mItem;
public:
MyItem* getItem() { return mItem.get(); }
};
void initialize(Container& container) {
unsigned char *p = reinterpret_cast<unsigned char*>(&container);
std::auto_ptr<MyItem> *ap = reinterpret_cast<std::auto_ptr<MyItem>*>(p + offsetof(Container, mItem));
ap->reset(new MyItem);
}
在另一方面,如果你的目的不是爲了改變mItem
本身,而是簡單地(重新)初始化MyItem
對象mItem
已經拿着,你可以使用爲getItem()
這一點,但只有當MyItem
對象事先已創建:
void initialize(Container &container) {
MyItem *item = container.getItem();
if (item) *item = MyItem();
}
您可以通過不允許012保證持有空指針擺在首位:
class Container {
private:
std::auto_ptr<MyItem> mItem;
public:
Container() : mItem(new MyItem) {}
Container(const Container &src) : mItem(new MyItem(src.getItem())) {}
Container& operator=(const Container &rhs) { mItem.reset(new MyItem(rhs.getItem())); return *this; }
MyItem& getItem() { return *mItem.get(); }
};
請停止使用'的std :: auto_ptr',在某些情況下,它可能是危險的,它已被從C++ 11贊成['性病棄用:: unique_ptr'](http://en.cppreference.com/w/cpp/memory/unique_ptr),而'std :: auto_ptr'將從C++ 17標準中刪除。 –
如果你只是想通過公共功能進行修改,爲什麼要保持私密?無論如何,'* container.getItem()= MyItem();'? –
還要注意'getItem'通過值返回存儲的指針*,所以在左邊執行任何賦值'getItem'的操作都不起作用。可能做例如'* container.getItem()= MyItem()'應該可以工作。它*不會繞過智能指針的整個「所有權」模型。 –