`
kmplayer
  • 浏览: 497282 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

设计模式之虚构造函数模式

阅读更多
1,虚构造函数模式:"现在还不知道需要什么类型的对象,但是有一些信息,请创建适当的对象."
2,实例代码:
#include <iostream>
#include <stdexcept>
#include <vector>
using namespace std;

class Shape
{
    Shape* s;
    Shape(const Shape&);
    Shape operator=(Shape&);
//禁止构造对象
//这里只给派生类动态创建时使用.
protected:
    Shape(){ s=0; }//注:"信封"中s指向实际对象.
    //"信件"中,s只是一个负荷,这里默认构造函数为"信件"将s赋值为0
public:
    virtual void draw(){ s->draw(); };
    virtual ~Shape() //这里将被调用两次
    //第一次派生类s!=0;
    //第二次,基类,此时s==0,delete s无操作.
    {
        cout<<"~Shape"<<endl;
        delete s;//注:delete 0合法,等价于无操作
    }
    class shape_error : public logic_error
    {
    public:
        shape_error(string type):logic_error("Cann't create shape: "+type){}
    };
    Shape(string type) throw(shape_error);
};

class Circle : public Shape
{
    Circle(){}//构造函数设为私有,只创建基类
    Circle(const Circle&);
    Circle operator=(Circle&);
    friend class Shape;
public:
    void draw(){ cout<<"Circle:Draw"<<endl; }
    ~Circle(){ cout<<"Circle:~Circle"<<endl; }
};

class Square : public Shape
{
    Square(){}//构造函数设为私有,只创建基类
    Square(const Square&);
    Square operator=(Square&);
    friend class Shape;
public:
    void draw(){ cout<<"Square:Draw"<<endl; }
    ~Square(){ cout<<"Square:~Square"<<endl; }
};

//核心
Shape::Shape(string type) throw(Shape::shape_error)
{
    if(type=="Circle")
        s=new Circle;
    else if(type=="Square")
        s=new Square;
    else throw shape_error(type);
}

char* sl[] = { "Circle", "Square", "Square", "Circle", "Circle", "Circle", "Square" };
int main()
{
    vector<Shape*> shapes;
    try
    {
        for(size_t i = 0; i < sizeof sl / sizeof sl[0]; i++)
            shapes.push_back(new Shape(sl[i]));//这里虚指针都是指向Shape的一个对象.
    } catch(Shape::shape_error& e)
    {
        cout << e.what() << endl;
        for(vector<Shape*>::iterator ite=shapes.begin();ite!=shapes.end();ite++)
        {
            delete *ite;
        }
        return EXIT_FAILURE;
    }
    for(size_t i = 0; i < shapes.size(); i++)
    {
        shapes[i]->draw();
    }
    //关于析构函数:从Shape的析构函数入口,第一次执行delete s,先派生类析构,然后基类析构,又一次执行delete s
    //此时派生类的s=0,不产生任何操作.
    for(vector<Shape*>::iterator ite=shapes.begin();ite!=shapes.end();ite++)
    {
        delete *ite;
        cout<<endl;
    }
    return 0;
}
分享到:
评论

相关推荐

    VC设计模式之消息映射

    主要是通过一个基类来定义一个公用接口,派生类动态实现此接口,派生类对象用基类的构造函数来记录,消息传送时,可以是每个派生类对象分开,...主要用到的知识有:C++的构造函数,析构函数,虚函数,vector的应用。

    C++将构造函数虚化,动态产生对象

    我们知道构造函数有一个必须遵守的规则,即构造函数不能定义为虚函数。但有一个具体的应用是要求是在不同的场景下通过一个指针或者引用生成不同的对象,这类似于类型的动态生成,即在执行期才能确定具体的对象。这...

    《设计模式》中文版

    内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...

    NET设计规范-.NET约定、惯用法与模式.part2

    5.3 构造函数的设计 117 5.4 事件的设计 123 5.5 字段的设计 130 5.6 操作符重载 132 5.6.1 重载operator== 136 5.6.2 类型转换操作符 136 5.7 参数的设计 138 5.7.1 枚举和布尔参数之间的选择 140 ...

    摩托罗拉C++面试题

    构造函数不能为虚函数,要构造一个对象,必须清楚地知道要构造什么,否则无法构造一个对象。 析构函数可以为纯虚函数。 10,拷贝构造函数相关问题,深拷贝,浅拷贝,临时对象等。 深拷贝意味着拷贝了资源和指针,而...

    NET设计规范-.NET约定、惯用法与模式.part1

    5.3 构造函数的设计 117 5.4 事件的设计 123 5.5 字段的设计 130 5.6 操作符重载 132 5.6.1 重载operator== 136 5.6.2 类型转换操作符 136 5.7 参数的设计 138 5.7.1 枚举和布尔参数之间的选择 140 ...

    程序员面试宝典-第三版(高清带目录)

    第1部分 求职过程  章 应聘求职  1.1 渠道  1.2 流程  第2章 简历书写  2.1 简历注意事项 ...第3部分 数据结构和设计模式 第4部分 操作系统、数据库和网络 第5部分 综合面试题 附录A 面试经历总结

    C++上机实验报告-实验五.docx

    基类构造函数的调用顺序是按照派生类定义时的顺序,而内嵌对象的构造函数调用顺序是按照成员在类C++上机实验报告-实验五全文共7页,当前为第2页。C++上机实验报告-实验五全文共7页,当前为第2页。中声明的顺序。 C++...

    计算机类基础问题

     C++语言考查的重点主要有:多继承,抽象类,虚函数,拷贝构造函数,析构函数, 动态联编,多态,const,static。以下是我面试中遇到的问题: 1)你听说过拷贝构造函数吗?能具体说一下它的作用吗?(汉略) 。。。...

    C++ Primer中文版(第5版)李普曼 等著 pdf 1/3

     13.6.2 移动构造函数和移动赋值运算符 473  13.6.3 右值引用和成员函数 481  小结 486  术语表 486  第14章 操作重载与类型转换 489  14.1 基本概念 490  14.2 输入和输出运算符 494  14.2.1 重载输出...

    C++Primer(第5版 )中文版(美)李普曼等著.part2.rar

     13.6.2 移动构造函数和移动赋值运算符 473  13.6.3 右值引用和成员函数 481  小结 486  术语表 486  第14章 操作重载与类型转换 489  14.1 基本概念 490  14.2 输入和输出运算符 494  14.2.1 重载输出...

    Absolute C++中文版(原书第2版)-完美的C++教程,文档中还包含英文版

    8.2.1 构造函数的自动类型转换 221 8.2.2 友元函数 222 8.2.3 友元类 225 8.3 引用和其他操作符重载 226 8.3.1 引用 226 8.3.2 重载“《”和“》” 228 8.3.3 赋值操作符 234 8.3.4 重载自增和自减操作符 ...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    他是我国计算机普及和高校计算机基础教育开拓者之一,现任全国高等院校计算机基础教育研究会会长、教育部全国计算机应用技术证书考试委员会主任委员。 谭浩强教授创造了3个世界纪录:(1)20年来他(及和他人合作)...

    C++ Primer第四版【中文高清扫描版】.pdf

    15.4.5 构造函数和析构函数中的虚函数 497 15.5 继承情况下的类作用域 497 15.5.1 名字查找在编译时发生 498 15.5.2 名字冲突与继承 498 15.5.3 作用域与成员函数 499 15.5.4 虚函数与作用域 500 15.6 纯虚函数 502 ...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    他是我国计算机普及和高校计算机基础教育开拓者之一,现任全国高等院校计算机基础教育研究会会长、教育部全国计算机应用技术证书考试委员会主任委员。 谭浩强教授创造了3个世界纪录:(1)20年来他(及和他人合作)...

    c++语言程序设计(第三版)

    4.4 构造函数和析构函数 4.5 类的组合 4.6 类模板 4.7 面向对象标记 4.8 小结 习题 第5章 C++程序的结构 5.1 作用域与可见性 5.2 生存期 5.3 数据与函数 5.4 静态成员 5.5 友元 5.6 共享数据的保护 5.7 多文件结构...

    传智播客扫地僧视频讲义源码

    本教程共分为5个部分,第一部分是C语言提高部分,第二部分为C++基础部分,第三部分为C++进阶部分,第四部分为C、C++及数据结构基础部分,第五部分为C_C++与设计模式基础,内容非常详细. 第一部分 C语言提高部分目录...

    深入.Net平台和C#编程

    深入.Net平台和C#编程 值类型和引用类型 集合操作 类、对象、构造函数、方法重载、静态方法、对象交互 面向对象特性:继承、多态 虚方法 方法重写 抽象类 设计模式 TreeView 控件 XML解析 读写文本文件 文件和文件夹...

    C++编程思想(Thinking in C++)完美版pdf

    第11章 引用和拷贝构造函数 第12章 运算符重载 第13章 动态对象创建 第14章 继承和组合 第15章 多态性和虚函数 第16章 模板介绍 附录A 编码风格 附录B 编程准则 附录C 推荐读物 索引 第2卷:实用编程技术 出版者的话...

Global site tag (gtag.js) - Google Analytics