扶沟县 和静县 赤水市 商河县 仁寿县 祥云县 银川市 格尔木市 景洪市 宜川县 大姚县 冷水江市 大余县 通州区 江北区 竹山县

文章导航软件下载单机游戏安卓资源苹果资源

pc软件网络操作系统办公服务器软件评测

安卓新闻资讯应用教程刷机教程安卓游戏攻略tv资讯综合安卓评测

苹果ios资讯越狱备份教程美化教程mac教程

单机游戏角色扮演即时战略棋牌游戏体育竞技模拟经营游戏工具

网游dnf活动lol周免英雄lol礼包

手游最新动态手游评测手游活动手游问答

您的位置:角色扮演 → 怪物猎人世界新装备介绍 怪物猎人世界新装备新系统一览

魔卡少女樱_C++的代理类

标签:柱塞阀 麻将胡牌的几种模式

怎样在一个容器中包含类型不同,但是彼此有关系的对象?众所周知,C++的容器只能存放类型相同的元素,所以直接在一个容器中存储不同类型的对象本身是不可能的,只能通过以下两种方案实现:

1. 提供一个间接层,在容器中存放对象的指针而不是破晓之爱_2018年最新新闻网对象本身。

2. 通过代理类实现。

class Animal
{
public:
    virtual void Eat() = 0;
};

class Cat : public Animal{};
class Dog : public Animal{};
class Bird : public Animal{};

在上面我们看到有一个虚基类和三个继承类,下面分别用两种方案来实现一个容器存放不同类型但又互相关联的类。

1.通过指针实现

Animal* animals_array[3];
Cat cat;
Dog dog;
Bird bird;
animals_array[0] = &cat;
animals_array[1] = &dog;
animals_array[2] = &bird;

这样会带来一个问题,就是容器中的指针指向的对象如果被销毁,这个指针就会变成野指针,就像下面这样:

Animal* animals_array[3];
do
{
    Cat cat;
    Dog dog;    
    Bird bird;
    animals_array[0] = &cat;
    animals_array[1] = &dog;
    animals_array[2] = &bird;
}while(0);
//此时对象已经被析构,容器中的指针指向未知内容

也可以换一种方式,构造一个新的动态对象,将其地中国好歌曲_2018年最新新闻网址放在容器中,这样就可以避免对象析构导致指针失效的问题:

Cat cat;
animals_array[0] = new Cat(cat);

天王_2018年最新新闻网样会曾加额外的内存开销,并且可能出现容器中两个指针同时指向一个对象的情况。
所以,在容器中存放不同对象的指针并不是一个很好的解决方案。

2.通过代理类实现

实现代码如下:

class Animal
{
public:
    virtual void Eat() = 0;

    //copy函数,构造一个基于自身对象类型的对象
    virtual Animal* copy() const = 0;

    virtual ~Animal() {}
};

class Cat : public Animal
{
public:
    virtual void Eat()
    {
        std::cout << "cat eat." << std::endl;
    }

    virtual Animal* copy() const
    {
        // 返回一个以自身作为参数构造的Cat类型的对象
        return new Cat(*this);
    }
};

class Dog : public Animal
{
public:

    virtual void Eat()
    {
        std::cout << "dog eat." << std::endl;
    }

    virtual Animal* copy() con倩碧_2018年最新新闻网st
    {
        // 返回一个以自身作为参数构造的Dog类型的对象
        return new Dog(*this);
    }
};

class Bird : public Animal东来顺_2018年最新新闻网
{
public:

    virtual void Eat()
    {
        std::cout << "bird eat." << std::endl;
    }

    virtual Animal* copy() const
    {
        // 返回一个以自身作为参数构造的Bird类型的对象
        return new Bird(*this);
    }
};

//代理类
class AnimalSurrogate
{
public:
    AnimalSurrogate() :pa(NULL) {}

    AnimalSurrogate(const Animal& ani)
    {
        pa = ani.copy();
    }

    //拷贝构造
    AnimalSurrogate(const AnimalSurrogate& ani_srg)
    {
        pa = ani_srg.pa != nullptr ? ani_srg.pa->copy() : nullptr;
    }

    ~AnimalSurrogate()
    {
        if (pa != nullptr)
        {
            delete pa;
            pa = nullptr;
        }
    }

    //重载 = 操作符
    AnimalSurrogate& operator=(const AnimalSurrogate& ani_srg)
    {
        if (this != &ani_srg)
        {
            delete pa;
            pa = ani_srg.pa != nullptr ? ani_srg.pa->copy() : nullptr;
        }
        return *this;
    }

    //将基类中的公共函数搬过来,这样就可以通过代理类直接访问这些方法
    void Eat()
    {
        if (pa == nullptr)
        {
            throw "empty AnimalSurrogate.Eat()";
        }
        return pa->Eat();
    }

private:
    Animal* pa;//存储基类的指针
};

通过代码可以看出来,所谓的代理类,就是构造一个新的类,这个类中包含关联的基类类型的指针,该指针可以指向不同类型但又相互关联的子类对象,通过指针可以转调对象的方法,同时实现内存的管理。代理类的实用方法如下:

Cat cat;
Dog dog;
Bird bird;

arr[0] = AnimalSurrogate(cat);
arr[1] = AnimalSurrogate(dog);
arr[2] = AnimalSurrogate(bird);

arr[0].Eat();//输出 cat eat.
arr[1].Eat();//输出 dog eat.
arr[2].Eat();//输出 bird eat.

总结:代理类的的每个对象都代表人性的弱点_2018年最新新闻网另一个对象,该对象可以使位于一个完成继承层次中的任何类的对象。通过在容器中用代理对象而不是对象本身的方式,实现容器中存放不同类型的对象

使用代理类的优缺点如下:

  • 优点:使用代理类比直接在容器中存放不同对象的指针更安全,便于实现内存管理。
  • 缺点:内存开销太大,放入容器的每个对象都需要拷贝一次,不够灵活。

为了避免对象的拷贝,可以通过句柄类来实现,关于句柄类的原理和使用在下一篇问文章中作介绍。

当前文章:http://www-tigongshi-com.qiedata.cn/6gcd/e28e3_153176.html

发布时间:2019-09-16 00:27:06

澳门银河娱乐官网下载  2949.com澳门银河娱乐  澳门银河娱乐场yh163am.com  朗普演讲模仿巴黎恐袭凶手 被指玷污遇难者亡灵  澳门银河2949所有网址  919银河优越会  澳门银河2949所有网址李易峰凌晨发文庆31岁生日 何炅魏大勋等送祝福  澳门银河娱乐送彩金网站  银河优越会下载罗晋拍打戏拒用替身:受不了动作戏不真实  银河国际中心游戏厅  

相关阅读 遵义户外运动徒步协会莅临贵州汉台酒业参观考察《刺客信条:奥德赛》正式公布:斯巴达怒踹圣骑士Facebook:若想继续在硅谷混,就必须解决高房价问题

文章评论
发表评论

热门文章 米家驱蚊器发布:无需接入电源,售价59元城乡居民医保“钱袋子”购买力将提升日本熊本县造路飞铜像遭民众反对 政府回应计划不变

最新文章 英法德抢救伊核协议 以总理将赴欧洲硬“劝离”金正恩:朝鲜对半岛无核化意志是“不变、一贯和坚定的” 东京飞香港一载137人客机起飞前机体冒烟,8名乘客不适滴滴官方教程:四个关于遗落物品的小贴士Bypass 360主机卫士SQL注入防御(多姿势)

人气排行 重庆高山上的蓝莓园让“60”农民居家就业vivo NEX旗舰机入网工信部:6月12日发布苹果iPhone 7全球价格地图:美国最便宜Facebook:若想继续在硅谷混,就必须解决高房价问题1500款名茶东莞国际茶博会展出传承中国茶文化大数据加速渗透实体经济生活靠一单单跑出来 7000万“网约工”缺保障机制