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()'应该可以工作。它*不会绕过智能指针的整个“所有权”模型。 –