免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9176 | 回复: 6

[C++] error: taking address of temporary [-fpermissive] [复制链接]

论坛徽章:
0
发表于 2012-09-20 21:02 |显示全部楼层
本帖最后由 时间看来 于 2012-09-20 21:16 编辑
  1. ///**
  2. //欢迎转载,请注明出处。
  3. //
  4. //Flyweight模式
  5. //
  6. //  
  7. //官方描述:
  8. //
  9. //意图
  10. //        运用共享技术有效地支持大量细粒度的对象。
  11. //
  12. //适用性
  13. //        1、一个应用程序使用了大量的对象。
  14. //        2、完全由于使用大量的对象,造成很大的存储开销。
  15. //        3、对象的大多数状态都可变为外部状态。
  16. //        4、如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
  17. //        5、应用程序不依赖于对象标识。由于Flyweight 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
  18. //
  19. //
  20. //我的描述:
  21. //
  22. //        在开始设计类的时候,很自然的根据现实情况把某些属性作为类的一部分,例如设计一个图书的管理系统,每本书都有出版社、
  23. //编号、作者、价钱等的属性,所以这个书的类可以这样设计:
  24. //
  25. //class Book
  26. //{
  27. //public:
  28. //        string GetPublish()        {return m_publishCompany;}
  29. //        string GetWriter()  {return m_writer;}
  30. //        int GetBookID()                {return m_bookID;}
  31. //        int GetPrice()                {return m_price;}
  32. //        string GetName()    {return m_name;}
  33. //
  34. //        void SetPublish(string &s)        {m_publishCompany = s;}
  35. //        void SetWriter(string &s)        {m_writer = s;}
  36. //        void SetBookID(int id)                {m_bookID = id;}
  37. //        void SetPrice(int price)        {m_price = price;}
  38. //        void SetName(string &s)                {m_name = s;}
  39. //
  40. //private:
  41. //        string m_publishCompany;        // 出版社
  42. //        string m_writer;                        // 作者
  43. //        int        m_bookID;                                // 书籍编号
  44. //        int m_price;                                // 价钱
  45. //        string m_name;                                // 书名
  46. //};
  47. //
  48. //        这非常自然。但是随着系统的开发和试运行,这种设计就表现出一些不足的地方了,例如一般图书会非常多,成千上万本;
  49. //如果每本书都耗费多一些空间,那整个系统所耗费的空间是不可想象的。所以,我们就要想办法来解决这个问题。
  50. //        然后高明的面向对象设计者就想出了这个办法,把一些相同的属性(把它叫做“享元”)提取出来,并用一个表来管理(池),
  51. //这就是Flyweight模式的思想所在。好了,我们现在来看看示意图:
  52. //
  53. //
  54. //  
  55. //
  56. //
  57. //        这里的ConcreteFlyweight就是需要共享的属性(享元),例如上面的出版社和作者,这里的UnsharedConcreteFlyweight就是
  58. //不用共享的属性(书籍编号和价钱)。
  59. //
  60. //    想象一下系统里面Book类的使用:
  61. //        1、先看看不用共享模式:
  62. //        
  63. //        Book book1, book2, book3;
  64. //        book1.SetPublish("机械工业出版社");
  65. //        book1.SetWriter("候捷");
  66. //        book1.SetBookID(0000);
  67. //        book1.SetPrice(20);
  68. //        book1.SetName("C++好野");
  69. //
  70. //        book2.SetPublish("人民邮电出版社");
  71. //        book2.SetWriter("候捷");
  72. //        book2.SetBookID(0001);
  73. //        book2.SetPrice(30);
  74. //        book2.SetName("C++是好劲");
  75. //        
  76. //        book3.SetPublish("机械工业出版社");
  77. //        book3.SetWriter("一雨田");
  78. //        book3.SetBookID(0002);
  79. //        book3.SetPrice(50);
  80. //        book3.SetName("C++无得顶,我是铁头功...");        
  81. //        
  82. //        这里有两个“机械工业出版社”和两个“候捷”,重复了。如果使用共享模式的话,这里的浪费就可以避免了。
  83. //        别看这里只有两个,想象一下成千上万本书时的空间浪费...
  84. //
  85. //        2、使用共享模式,把出版社和作者两个属性作为享元(Fly~~Weight)
  86. //        PublishFlyweightFactory pff;
  87. //        WriterFlyweightFactory wff;
  88. //        Book book1, book2, book3;
  89. //
  90. //        book1.SetPublish(pff.GetPublish("机械工业出版社")->GetName());
  91. //        book1.SetWriter(wff.GetWriter("候捷")->GetName());
  92. //        book1.SetBookID(0000);
  93. //        book1.SetPrice(20);
  94. //        book1.SetName("C++好野");
  95. //
  96. //        book2.SetPublish(pff.GetPublish("人民邮电出版社")->GetName());
  97. //        book2.SetWriter(wff.GetWriter("候捷")->GetName());
  98. //        book2.SetBookID(0001);
  99. //        book2.SetPrice(30);
  100. //        book2.SetName("C++是好劲");
  101. //
  102. //        book3.SetPublish(pff.GetPublish("机械工业出版社")->GetName());
  103. //        book3.SetWriter(wff.GetWriter("一雨田")->GetName());
  104. //        book3.SetBookID(0002);
  105. //        book3.SetPrice(50);
  106. //        book3.SetName("C++无得顶,我是铁头功...");
  107. //
  108. //        为什么使用了PublishFlyweightFactory和WriterFlyweightFactory之后就可以节省空间了呢?
  109. //
  110. //        奥妙就在于GetPublish和GetWriter的实现:
  111. //        
  112. //        PublishFlyweight* GetPublish(string key)
  113. //        {
  114. //                PublishFlyweight *p;
  115. //                mapPublish::iterator it;
  116. //                it = mapPublish.find(key);
  117. //
  118. //                // 存在这个Writer
  119. //                if(it != mapPublish.end() )
  120. //                        p = it;
  121. //
  122. //                else
  123. //                {// 插入这个PublishFlyweight
  124. //                        
  125. //                        p = new PublishFlyweight(key);
  126. //                        mapPublish[key] = p;
  127. //                }
  128. //
  129. //                return p;
  130. //        }
  131. //        
  132. //        GetWriter的实现大同小异,这里就不列出来了,请看详细代码里的实现。
  133. //*/

  134. // Flyweight.cpp

  135. #pragma warning(disable: 4786)

  136. #include <iostream>
  137. #include <map>
  138. #include <string>
  139. #include <cstring>
  140. using namespace std;


  141. class Book
  142. {
  143. public:
  144.         string GetPublish() {return *m_publishCompany;}
  145.         string GetWriter()  {return *m_writer;}
  146.         int GetBookID()  {return m_bookID;}
  147.         int GetPrice()  {return m_price;}
  148.         string GetName()    {return m_name;}
  149.         
  150.         void SetPublish(string *s) {m_publishCompany = s;}
  151.         void SetWriter(string *s) {m_writer = s;}
  152.         void SetBookID(int id)  {m_bookID = id;}
  153.         void SetPrice(int price) {m_price = price;}
  154.         void SetName(string s)  {m_name = s;}
  155.         
  156. private:
  157.         string *m_publishCompany; // 出版社
  158.         string *m_writer;   // 作者
  159.         int m_bookID;    // 书籍编号
  160.         int m_price;    // 价钱
  161.         string m_name;    // 书名
  162. };

  163. class PublishFlyweight
  164. {
  165. public:
  166.         PublishFlyweight(string s)
  167.         {
  168.                 m_name = s;
  169.         }
  170.         string GetName()
  171.         {
  172.                 return m_name;
  173.         }
  174.         
  175. private:
  176.         string m_name;
  177. };

  178. class PublishFlyweightFactory
  179. {
  180. public:
  181.         PublishFlyweight* GetPublish(string key)
  182.         {
  183.                 PublishFlyweight *p;
  184.                 map<string, PublishFlyweight*>::iterator it;
  185.                 it = mapPublish.find(key);
  186.                

  187.                 // 存在这个出版社
  188.                 if(it != mapPublish.end() )
  189.                 {
  190.                         // 这里可能有点难懂,请查阅STL的帮助文档
  191.                         // 其实second就是指 map<string, PublishFlyweight*> 的 PublishFlyweight*
  192.                         p = (*it).second;
  193.                         cout << "已经有这个出版社: " << p->GetName() << " 你节省了" << strlen(p->GetName().c_str()) << "字节的空间" << endl;
  194.                 }
  195.                
  196.                 else
  197.                 {// 插入这个PublishFlyweight
  198.                         
  199.                         p = new PublishFlyweight(key);
  200.                         mapPublish[key] = p;
  201.                 }
  202.                
  203.                 return p;
  204.         }
  205.         
  206. private:
  207.         map<string, PublishFlyweight*> mapPublish;
  208. };

  209. class WriterFlyweight
  210. {
  211. public:
  212.         WriterFlyweight(string s)
  213.         {
  214.                 m_name = s;
  215.         }
  216.         string GetName()
  217.         {
  218.                 return m_name;
  219.         }
  220.         
  221. private:
  222.         string m_name;
  223. };

  224. class WriterFlyweightFactory
  225. {
  226. public:
  227.         WriterFlyweight* GetWriter(string key)
  228.         {
  229.                 WriterFlyweight *p;
  230.                 map<string, WriterFlyweight*>::iterator it;
  231.                 it = mapWriter.find(key);
  232.                
  233.                 // 存在这个Writer
  234.                 if(it != mapWriter.end() )
  235.                 {
  236.                         // 这里可能有点难懂,请查阅STL的帮助文档
  237.                         // 其实second就是指 map<string, WriterFlyweight*> 的 WriterFlyweight*
  238.                         p = (*it).second;
  239.                         cout << "已经有这个作者名字: " << p->GetName() << " 你节省了" << strlen(p->GetName().c_str()) << "字节的空间" << endl;
  240.                 }
  241.                
  242.                 else
  243.                 {// 插入这个PublishFlyweight
  244.                         
  245.                         p = new WriterFlyweight(key);
  246.                         mapWriter[key] = p;
  247.                 }
  248.                
  249.                 return p;
  250.         }
  251.         
  252. private:
  253.         map<string, WriterFlyweight*> mapWriter;
  254. };


  255. void ShowBookInfo(Book book)
  256. {
  257.         cout << "书名:" << book.GetName() << endl;
  258.         cout << "编号:" << book.GetBookID() << endl;
  259.         cout << "价钱:" << book.GetPrice() << endl;
  260.         cout << "出版:" << book.GetPublish() << endl;
  261.         cout << "作者:" << book.GetWriter() << endl;
  262.         cout << endl;
  263. }

  264. int main()
  265. {
  266.         PublishFlyweightFactory pff;
  267.         WriterFlyweightFactory wff;
  268.         Book book1, book2, book3;
  269.         
  270.         book1.SetPublish( &(pff.GetPublish("机械工业出版社")->GetName()) );
  271.         book1.SetWriter( &(wff.GetWriter("候捷")->GetName()) );
  272.         book1.SetBookID(0000);
  273.         book1.SetPrice(20);
  274.         book1.SetName(string("<<C++好野>>"));
  275.         
  276.         ShowBookInfo(book1);
  277.         
  278.         book2.SetPublish( &(pff.GetPublish("人民邮电出版社")->GetName()) );
  279.         book2.SetWriter( &(wff.GetWriter("候捷")->GetName()) );
  280.         book2.SetBookID(0001);
  281.         book2.SetPrice(30);
  282.         book2.SetName(string("<<C++是好劲>>"));
  283.         
  284.         ShowBookInfo(book2);
  285.         
  286.         book3.SetPublish( &(pff.GetPublish("机械工业出版社")->GetName()) );
  287.         book3.SetWriter( &(wff.GetWriter("一雨田")->GetName()) );
  288.         book3.SetBookID(0002);
  289.         book3.SetPrice(50);
  290.         book3.SetName(string("<<C++无得顶,我是铁头功...>>"));
  291.         
  292.         ShowBookInfo(book3);

  293.         return 0;
  294. }
复制代码

编译信息:

  1. **** Build of configuration Debug for project DesignPattern_one ****

  2. **** Internal Builder is used for build               ****
  3. g++ -O0 -g3 -Wall -c -fmessage-length=0 -o Flyweight.o ..\Flyweight.cpp
  4. ..\Flyweight.cpp:137:0: warning: ignoring #pragma warning  [-Wunknown-pragmas]
  5. ..\Flyweight.cpp: In function 'int main()':
  6. ..\Flyweight.cpp:283:65: error: taking address of temporary [-fpermissive]
  7. ..\Flyweight.cpp:284:53: error: taking address of temporary [-fpermissive]
  8. ..\Flyweight.cpp:291:65: error: taking address of temporary [-fpermissive]
  9. ..\Flyweight.cpp:292:53: error: taking address of temporary [-fpermissive]
  10. ..\Flyweight.cpp:299:65: error: taking address of temporary [-fpermissive]
  11. ..\Flyweight.cpp:300:55: error: taking address of temporary [-fpermissive]
  12. Build error occurred, build is stopped
  13. Time consumed: 1459  ms.
复制代码

首先,既然网友晒出的代码,应该是经过测试过的。难道是因为我使用的编译器,会产生出这个错误!
这是怎么回事呢?
这个临时变量是指的哪个?
该如何修改呢?我想了哈,没有搞定~

谢谢您的回答!

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2012-09-20 21:54 |显示全部楼层
操作了临时内存?

网友的代码难道就一定是正确的? 反思.

论坛徽章:
0
发表于 2012-09-20 22:03 |显示全部楼层
本帖最后由 时间看来 于 2012-09-20 22:21 编辑

回复 2# linux_c_py_php


    谢谢你热心的回答。昨天你也解决了我的一个困惑,多谢!
    嗯,自己运行下,改一改,理解得更好。

    pff.GetPublish("机械工业出版社"),返回的是指针啊。
    动态分配的内存,p = new WriterFlyweight(key);还没有delete啊。&(pff.GetPublish("机械工业出版社")->GetName())有什么问题呢?

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2012-09-20 22:06 |显示全部楼层
&(pff.GetPublish("机械工业出版社")->GetName())

你自己都分析完了... 还没反应过来么-, -   

GetPublish返回的是new出来的对象的话, 你没有留住那个内存的地址, 你就没机会释放掉它, 就是内存泄漏了.

论坛徽章:
0
发表于 2012-09-20 22:20 |显示全部楼层
回复 4# linux_c_py_php


    在这个应用程序结束前,如果分配的内存不再用到,那才算泄漏吧。
     pff.GetPublish("机械工业出版社"),得到分配的PublishFlyweight(key),不能用吗?
     我尝试return mapWriter[key];可还是不行。

    印象中,应用程序结束后,泄漏的内存会被回收。所以这个小程序可以忽略这个问题吧,虽然不太好。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2012-09-20 22:24 |显示全部楼层
不能忽略... 内存泄漏是不允许的, 一个长时间运行的程序一直泄漏下去就崩溃了.

进程退出内存都是会回收的, 这个与内存泄漏没有任何关系.

论坛徽章:
0
发表于 2012-09-20 22:38 |显示全部楼层
回复 6# linux_c_py_php


    嗯,多谢指教~
    我在看看这里该怎么办。我对动态分配内存的使用还不熟悉~

    我下线了哈。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP