最多一次:指向任何特定对象的指针在任何时间点最多可以存在一个容器对象中。
存在性:在插入指向它的指针之前,必须动态分配对象。
所有权:一旦插入指向对象的指针,该对象就成为容器的属性。其他人不得以任何方式使用或修改它。
守恒:当从容器中删除指针时,要么必须将指针插入到某个容器中,要么必须删除其所指对象。
这些是我给出的相应定义。我很难理解每个术语中使用的各种术语,我希望这里有人可以准确解释每个术语的含义以及如何使用它们来确保良好的编程实践。
最多一次:指向任何特定对象的指针在任何时间点最多可以存在一个容器对象中。
存在性:在插入指向它的指针之前,必须动态分配对象。
所有权:一旦插入指向对象的指针,该对象就成为容器的属性。其他人不得以任何方式使用或修改它。
守恒:当从容器中删除指针时,要么必须将指针插入到某个容器中,要么必须删除其所指对象。
这些是我给出的相应定义。我很难理解每个术语中使用的各种术语,我希望这里有人可以准确解释每个术语的含义以及如何使用它们来确保良好的编程实践。
例如,假设您有以下类定义:
class Container {
public:
// construct a container instance by making it point to an item
Container(Item *pItem) : m_pItem(pItem) { }
private:
Item *m_pItem;
};
class Item {
public:
change() {
// do something to change the item
}
private:
// some private data
};
最多一次:指向任何特定对象的指针在任何时间点最多可以存在一个容器对象中。
有两个Container
带有指向同一个实例的指针的实例Item
会违反这一点:
Item *pItem = new Item(); // construct a new Item
Container c1(pItem); // create a new container pointing to this item
Container c2(pItem); // WRONG: create another container pointing to the same item
存在性:在插入指向它的指针之前,必须动态分配对象。
动态分配对象通常意味着使用运算符创建对象的新实例,该运算符new
返回指向在堆内存(而不是堆栈)上分配的新创建对象的指针。违反此规定的两个例子是:
Item *pItem = NULL;
Container c1(pItem); // WRONG: pItem is not dynamically allocated; it is NULL
Item item;
Container c2(&item); // WRONG: &item does not point to a dynamically allocated heap
// object; the object is on stack;
所有权:一旦插入指向对象的指针,该对象就成为容器的属性。其他人不得以任何方式使用或修改它。
当一个对象存在于内存中时,任何具有该对象的指针或引用的对象或函数都可能修改它(除非声明了指针或引用const
):
Item *pItem = new Item(); // the function containing this code obviously has a pointer
// to the newly created item
Container c(pItem); // let the container c own this item
pItem->change(); // WRONG: attempt to modify an object owned by c
守恒:当从容器中删除指针时,要么必须将指针插入到某个容器中,要么必须删除其所指对象。
这意味着当容器不再想要“拥有”(定义与上面完全相同的含义)它指向的项目实例时,它必须将“所有权”转移给另一个容器,或者删除该项目。对类的以下修改Container
实现了此行为:
class Container {
public:
removeItem() {
delete m_pItem; // deallocate the item instance owned by this container
// the item is no longer owned because it no longer exists
}
giveItemTo(const Container& other) {
other.m_pItem = m_pItem; // let the other container own this item instead
m_pItem = NULL; // the item is no longer owned by this container because the pointer is NULL
}
};