您的位置:首页 > 编程语言

设计模式简单代码之Flyweight模式

2008-08-27 09:30 537 查看
在一雨田的Blog有一篇关于Flyweight模式的文章: http://blog.csdn.net/dylgsy/archive/2006/08/10/1045678.aspx

但在编译运行时,问题产生了:出版社和作者显示不了。

一雨田原来的代码:

// Flyweight.cpp

#pragma warning(disable: 4786)

#include <iostream>

#include <map>

#include <string>

#include <stdlib.h>

using namespace std;

class Book

{

public:

string GetPublish() {return *m_publishCompany;}

string GetWriter() {return *m_writer;}

int GetBookID() {return m_bookID;}

int GetPrice() {return m_price;}

string GetName() {return m_name;}

void SetPublish(string *s) {m_publishCompany = s;}

void SetWriter(string *s) {m_writer = s;}

void SetBookID(int id) {m_bookID = id;}

void SetPrice(int price) {m_price = price;}

void SetName(string &s) {m_name = s;}

private:

string *m_publishCompany; // 出版社

string *m_writer; // 作者

int m_bookID; // 书籍编号

int m_price; // 价钱

string m_name; // 书名

};

class PublishFlyweight

{

public:

PublishFlyweight(string s)

{

m_name = s;

}

string GetName()

{

return m_name;

}

private:

string m_name;

};

class PublishFlyweightFactory

{

public:

PublishFlyweight* GetPublish(string key)

{

PublishFlyweight *p;

map<string, PublishFlyweight*>::iterator it;

it = mapPublish.find(key);

// 存在这个出版社

if(it != mapPublish.end() )

{

// 这里可能有点难懂,请查阅STL的帮助文档

// 其实second就是指 map<string, PublishFlyweight*> 的 PublishFlyweight*

p = (*it).second;

cout << "已经有这个出版社: " << p->GetName() << " 你节省了" << strlen(p->GetName().c_str()) << "字节的空间" << endl;

}

else

{// 插入这个PublishFlyweight

p = new PublishFlyweight(key);

mapPublish[key] = p;

}

return p;

}

private:

map<string, PublishFlyweight*> mapPublish;

};

class WriterFlyweight

{

public:

WriterFlyweight(string s)

{

m_name = s;

}

string GetName()

{

return m_name;

}

private:

string m_name;

};

class WriterFlyweightFactory

{

public:

WriterFlyweight* GetWriter(string key)

{

WriterFlyweight *p;

map<string, WriterFlyweight*>::iterator it;

it = mapWriter.find(key);

// 存在这个Writer

if(it != mapWriter.end() )

{

// 这里可能有点难懂,请查阅STL的帮助文档

// 其实second就是指 map<string, WriterFlyweight*> 的 WriterFlyweight*

p = (*it).second;

cout << "已经有这个作者名字: " << p->GetName() << " 你节省了" << strlen(p->GetName().c_str()) << "字节的空间" << endl;

}

else

{// 插入这个PublishFlyweight

p = new WriterFlyweight(key);

mapWriter[key] = p;

}

return p;

}

private:

map<string, WriterFlyweight*> mapWriter;

};

void ShowBookInfo(Book book)

{

cout << "书名:" << book.GetName() << endl;

cout << "编号:" << book.GetBookID() << endl;

cout << "价钱:" << book.GetPrice() << endl;

cout << "出版:" << book.GetPublish() << endl;

cout << "作者:" << book.GetWriter() << endl;

cout << endl;

}

void main()

{

PublishFlyweightFactory pff;

WriterFlyweightFactory wff;

Book book1, book2, book3;

book1.SetPublish( &(pff.GetPublish("机械工业出版社")->GetName()) );

book1.SetWriter( &(wff.GetWriter("候捷")->GetName()) );

book1.SetBookID(0000);

book1.SetPrice(20);

book1.SetName(string("<<C++好野>>"));

ShowBookInfo(book1);

book2.SetPublish( &(pff.GetPublish("人民邮电出版社")->GetName()) );

book2.SetWriter( &(wff.GetWriter("候捷")->GetName()) );

book2.SetBookID(0001);

book2.SetPrice(30);

book2.SetName(string("<<C++是好劲>>"));

ShowBookInfo(book2);

book3.SetPublish( &(pff.GetPublish("机械工业出版社")->GetName()) );

book3.SetWriter( &(wff.GetWriter("一雨田")->GetName()) );

book3.SetBookID(0002);

book3.SetPrice(50);

book3.SetName(string("<<C++无得顶,我是铁头功...>>"));

ShowBookInfo(book3);

system("pause");

}

是什么原因呢?仔细分析其源代码,发现“book1.SetPublish( &(pff.GetPublish("机械工业出版社")->GetName()) );”这一行使用了临时变量,在取“pff.GetPublish("机械工业出版社")->GetName() ”返回一个临时变量,而再取临时变量的地址&,运行到下一行时,这个临时地址将变成一个无效的地址,指向任何值都可以出现。因此,编程中是严禁这样使用的,编程时都应注意此类问题。修改好的代码如下:

/*

来源:一雨田Blog

问题:出版社和作者显示不了

修改:qmroom

*/

// Flyweight.cpp

#include <iostream>

#include <map>

#include <string>

#include <stdlib.h>

using namespace std;

typedef char CHAR;

typedef CHAR *LPSTR;

typedef const CHAR *LPCSTR;

class Book

{

public:

string GetPublish() {return *m_publishCompany;}

string GetWriter() {return *m_writer;}

int GetBookID() {return m_bookID;}

int GetPrice() {return m_price;}

string GetName() {return m_name;}

void SetPublish(string *s) {m_publishCompany = s;}

void SetWriter(string *s) {m_writer = s;}

void SetBookID(int id) {m_bookID = id;}

void SetPrice(int price) {m_price = price;}

void SetName(LPCSTR s) {m_name = s;}

private:

string *m_publishCompany; // 出版社

string *m_writer; // 作者

int m_bookID; // 书籍编号

int m_price; // 价钱

string m_name; // 书名

};

class PublishFlyweight

{

public:

PublishFlyweight(string s)

{

m_name = new string(s);

}

virtual ~PublishFlyweight()

{

delete(m_name);

}

string *GetName()

{

return m_name;

}

private:

string *m_name;

};

class PublishFlyweightFactory

{

public:

PublishFlyweight* GetPublish(string key)

{

PublishFlyweight *p;

map<string, PublishFlyweight*>::iterator it;

it = mapPublish.find(key);

// 存在这个出版社

if(it != mapPublish.end() )

{

// 这里可能有点难懂,请查阅STL的帮助文档

// 其实second就是指 map<string, PublishFlyweight*> 的 PublishFlyweight*

p = (*it).second;

cout << "已经有这个出版社: " << *(p->GetName()) << " 你节省了" << strlen((*(p->GetName())).c_str()) << "字节的空间" << endl;

}

else

{

// 插入这个PublishFlyweight

p = new PublishFlyweight(key);

mapPublish[key] = p;

}

return p;

}

private:

map<string, PublishFlyweight*> mapPublish;

};

class WriterFlyweight

{

public:

WriterFlyweight(string s)

{

m_name = new string(s);

}

virtual ~WriterFlyweight()

{

delete(m_name);

}

string *GetName()

{

return m_name;

}

private:

string *m_name;

};

class WriterFlyweightFactory

{

public:

WriterFlyweight* GetWriter(string key)

{

WriterFlyweight *p;

map<string, WriterFlyweight*>::iterator it;

it = mapWriter.find(key);

// 存在这个Writer

if(it != mapWriter.end() )

{

// 这里可能有点难懂,请查阅STL的帮助文档

// 其实second就是指 map<string, WriterFlyweight*> 的 WriterFlyweight*

p = (*it).second;

cout << "已经有这个作者名字: " << *(p->GetName()) << " 你节省了" << strlen((*(p->GetName())).c_str()) << "字节的空间" << endl;

}

else

{

// 插入这个PublishFlyweight

p = new WriterFlyweight(key);

mapWriter[key] = p;

}

return p;

}

private:

map<string, WriterFlyweight*> mapWriter;

};

void ShowBookInfo(Book book)

{

cout << "书名:" << book.GetName() << endl;

cout << "编号:" << book.GetBookID() << endl;

cout << "价钱:" << book.GetPrice() << endl;

cout << "出版:" << book.GetPublish() << endl;

cout << "作者:" << book.GetWriter() << endl;

cout << endl;

}

void main()

{

PublishFlyweightFactory pff;

WriterFlyweightFactory wff;

Book book1, book2, book3;

book1.SetPublish( pff.GetPublish("机械工业出版社")->GetName() );

book1.SetWriter( wff.GetWriter("qmroom")->GetName() );

book1.SetBookID(0000);

book1.SetPrice(20);

book1.SetName(("<<C++好野>>"));

ShowBookInfo(book1);

book2.SetPublish( pff.GetPublish("人民邮电出版社")->GetName() );

book2.SetWriter( wff.GetWriter("qmroom")->GetName() );

book2.SetBookID(0001);

book2.SetPrice(30);

book2.SetName(("<<C++是好劲>>"));

ShowBookInfo(book2);

book3.SetPublish( pff.GetPublish("机械工业出版社")->GetName() );

book3.SetWriter( wff.GetWriter("一雨田")->GetName() );

book3.SetBookID(0002);

book3.SetPrice(50);

book3.SetName(("<<C++无得顶,我是铁头功...>>"));

ShowBookInfo(book3);

system("pause");

}

其实,这段代码还有很多可以修改的地方,以便提高性能和便于维护和使用。请看设计模式简单代码之Flyweight模式(二)

下一篇
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: