以值包含对象的容器通常无须担心所有权问题,因为它们清晰地拥有它们所
包含的对象
一个容器所包含的指针指向仅由这个容器使用的那些对象
处理所有权问题的最好方法是由客户程序员来选择
通过构造函数的一个参数来完成,它默认地指明所有权。
另外还有 读取和 设置 函数用来查看和修正 容器的所有权
如果容器内有用于删除对象的函数,容器所有权的状态通常会影响这个删除,
所以我们还可以找到在删除函数中控制销毁的选项
//: C16:OwnerStack.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Stack with runtime conrollable ownership
#ifndef OWNERSTACK_H
#define OWNERSTACK_H
template<class T> class Stack {
struct Link {
T* data;
Link* next;
Link(T* dat, Link* nxt)
: data(dat), next(nxt) {}
}* head;
bool own;
public:
Stack(bool own = true) : head(0), own(own) {}
~Stack();
void push(T* dat) {
head = new Link(dat,head);
}
T* peek() const {
return head ? head->data : 0;
}
T* pop();
bool owns() const { return own; }
void owns(bool newownership) {
own = newownership;
}
// Auto-type conversion: true if not empty:
operator bool() const { return head != 0; }
};
template<class T> T* Stack<T>::pop() {
if(head == 0) return 0;
T* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}
template<class T> Stack<T>::~Stack() {
if(!own) return;
while(head)
delete pop();
}
#endif // OWNERSTACK_H ///:~
默认行为是让容器去销毁它的对象,但我们可以通过修改构造函数的参数
或者使用owns() 读/写成员函数来改变这个行为
我们可能看到的大多数模板那样,整个实现包含在头文件中
下面是一个检验所有权能力的测试
//: C16:OwnerStackTest.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
//{L} AutoCounter
#include "AutoCounter.h"
#include "OwnerStack.h"
#include "../require.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
Stack<AutoCounter> ac; // Ownership on
Stack<AutoCounter> ac2(false); // Turn it off
AutoCounter* ap;
for(int i = 0; i < 10; i++) {
ap = AutoCounter::create();
ac.push(ap);
if(i % 2 == 0)
ac2.push(ap);
}
while(ac2)
cout << ac2.pop() << endl;
// No destruction necessary since
// ac "owns" all the objects
getchar();
} ///:~
ac2对象不拥有放在它里面的对象,因而ac就是对所有权员有责任的 主
容器。
在容器生命期内如果希望改变一个容器拥有它的对象,我们可以用owns()
做这件事
我们还有可能改变所有权的粒度,使得它以 object-by-object 为基础,但是
这将可能会使所有权问题的解决更趋复杂