构造函数和非成员函数虚拟化

  参考<<More Effective C++>>一书中的条款25:"将constructor和non-member function虚化",简单的将里面的代码实现。

  constructor虚化:即virtual constructor,是某种函数,视其获得的输入,可产生不同的类型的对象。它在许多情况下有用,其中之一就是从磁盘(或网络或磁带等)读取对象信息。这里我是直接从文件中根据读取到字符的不同构造不同的对象。

  non-member function虚化:即一个虚函数做实际工作,再写一个什么都不做的非虚函数,只负责调用虚函数。这里的虚函数即是print()输出函数。

  这些类的关系如下图(引用自More Effective C++)

               

  代码如下:

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <list>

using namespace std;

class NLComponent  //抽象基类
{
public:
    virtual ostream& print(ostream& s) const = 0;
    virtual ~NLComponent(){}
};

class TextBlock : public NLComponent  //子类一
{
public:
    TextBlock(string name): name(name){}
    ~TextBlock();
    virtual ostream& print(ostream& s) const ;
private:
    string name;  //名称
};

ostream& TextBlock::print(ostream& s) const
{
    s<<"TextBlock : "<<name<<endl;
    return s;
}

TextBlock::~TextBlock()
{
    cout<<"TextBlock Destroy"<<endl;
}

class Graphic : public NLComponent  //子类二
{
public:
    Graphic(string name): name(name){}
    ~Graphic();
    virtual ostream& print(ostream& s) const ;
private:
    string name;   //名称
};

ostream& Graphic::print(ostream& s) const
{
    s<<"Graphic : "<<name<<endl;
    return s;
}

Graphic::~Graphic()
{
    cout<<"Graphic Destroy"<<endl;
}

inline ostream& operator<<(ostream& s, const NLComponent& c)
{
    return c.print(s);
}

class NewLetter
{
public:
    NewLetter(ifstream &fin);
    ~NewLetter();
    void printAll();
private:
    list<NLComponent*> components;
};

NewLetter::NewLetter(ifstream &fin)
{
    string str;
    while (fin >> str)   //根据不同的信息,构造不同的子类对象,即构造函数虚拟化
    {
        if (-1 != str.find("TextBlock"))
        {
            components.push_back(new TextBlock(str));
        }
        else if (-1 != str.find("Graphic"))
        {
            components.push_back(new Graphic(str));
        }
    }
}

NewLetter::~NewLetter()
{
    for (list<NLComponent*>::const_iterator it = components.begin(); it != components.end(); ++it)
    {
        delete (*it);
    }
    components.clear();
}

void NewLetter::printAll()
{
    for (list<NLComponent*>::const_iterator it = components.begin(); it != components.end(); ++it)
    {
        cout<<**it;    //直接输出不同子类的信息,即虚拟化非成员函数
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    ifstream fin("components.txt");
    NewLetter *letter = new NewLetter(fin);
    letter->printAll();
    delete letter;
    return 0;
}

  运行界面:

                                

  其中components.txt文件的内容为:

TextBlock1
Graphic1
TextBlock2
Graphic2
TextBlock3
Graphic3
TextBlock4
Graphic4
TextBlock5
Graphic5
posted @ 2012-10-16 20:13  venow  阅读(937)  评论(2编辑  收藏  举报