C++编程思想 第1卷 第16章 模板介绍 打开和关闭所有权

以值包含对象的容器通常无须担心所有权问题,因为它们清晰地拥有它们所
包含的对象

一个容器所包含的指针指向仅由这个容器使用的那些对象

处理所有权问题的最好方法是由客户程序员来选择

通过构造函数的一个参数来完成,它默认地指明所有权。 
另外还有 读取和 设置 函数用来查看和修正 容器的所有权
如果容器内有用于删除对象的函数,容器所有权的状态通常会影响这个删除,
所以我们还可以找到在删除函数中控制销毁的选项

//: 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 为基础,但是
这将可能会使所有权问题的解决更趋复杂

    原文作者:eyetired
    原文地址: https://blog.csdn.net/eyetired/article/details/81457911
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞