zoukankan      html  css  js  c++  java
  • 【C++沉思录】代理类

    1、考虑下面的需求,把一组类型不同,但是相互关联的对象放入容器中,比如Animal,Dog,Cat对象。
    2、容器只能包含一组 类型相同的对象,Animal,Dog,Cat对象是没有办法放入容器中的。
    3、怎么解决上面的问题?
    假设容器为vector,可以使用vector<Animal>,这会导致一个新问题,因为vector存储的是对象副本,子类放入vector<Animal>发生对象切割,不可能具备多态的性质。

    怎么解决上面的问题?
    ---------------------------------------------------------------------------------------------------------------------
    经典的解决办法:
    vector中存储Animal指针,这会带来如下问题:
    1、Dog d; v.push_back(&d); d是局部对象,离开作用域会自动销毁,容器中的指针指向一堆垃圾。
    2、为了解决上面的问题,使用 v.push_back(new Dog(d)); 这会带来动态内存管理的负担,考虑把v[j] 赋值给v[i],
    3、v[j] = v[i]; 两个指针指向同一个对象,v[j]和v[i] 不知道彼此,都不释放,内存泄露,都释放,行为未定义。
    4、对v[i]做一个副本,由于不知道v[i]的真实类型,使用v[j] = new Animal(v[i]); 这又发生对象切割。
    5、解决对象的切割,使用virtual clone方法,如下:v[j] = v[i].clone();

    ---------------------------------------------------------------------------------------------------------------------
    使用代理类,对指针Animal* 封装,栈上对象管理动态内存,实现指针的自动释放。
    如下:

    AnimalProxy::AnimalProxy():_pa(NULL)
    {
    
    }
    
    AnimalProxy::~AnimalProxy()
    {
    delete _pa;
    }
    
    // 注意:类中可以访问自己的private成员,也可以访问rhs的private成员
    AnimalProxy::AnimalProxy(const AnimalProxy& rhs)
    {
    _pa = (rhs._pa != NULL ? rhs._pa->Clone():NULL);
    }
    
    AnimalProxy& AnimalProxy::operator=(const AnimalProxy& rhs)
    {
    if(this != &rhs) // 等同测试
    {
    delete _pa; // delete NULL 也没有问题
    _pa = (rhs._pa == NULL ? rhs._pa->Clone():NULL); // 指针为NULL判断
    }
    return *this; // 返回引用
    }
    
    AnimalProxy::AnimalProxy(const Animal& animal):_pa(animal.Clone())
    {
    
    }
  • 相关阅读:
    使用 Prism.js 实现代码高亮
    Win10系统如何删除网络及修改网络名称
    CRT和PEM格式证书转换
    CentOS如何修改主机名
    crt格式证书转换为pem格式
    CentOS安装wget命令
    自适应(响应式)网页中的几个关键分辨率
    java中的I/O流学习(1)
    有种心态,我不知该如何表达
    java学习笔记—Scanner
  • 原文地址:https://www.cnblogs.com/nzbbody/p/4575590.html
Copyright © 2011-2022 走看看