免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5911 | 回复: 5
打印 上一主题 下一主题

[C++] C++类的构造函数初始化列表,的一个问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-09-19 21:54 |只看该作者 |倒序浏览
本帖最后由 时间看来 于 2012-09-19 22:36 编辑

本来我的C++基础知识都掌握得不好。
最近却尝试着看一些设计模式东西,差不多以《[设计模式:可复用面向对象软件的基础].(Design.Patterns:Elements.of.Reusable.Object-Oriented.Software).Erich.Gamma》为参考,但是使用的代码示例却不是这本书的。在网上找了一些示例:
  1. /**********************************************************************************************************\
  2. * 作者:一雨田(http://blog.csdn.net/dylgsy/)
  3. *
  4. * Decorator模式:
  5. * 动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类
  6. * 更为灵活。
  7. * 由于Decorator模式仅从外部改变组件,因此组件无需对它的装饰有任何了解;也就是说,
  8. * 这些装饰对该组件是透明的。
  9. \**********************************************************************************************************/

  10. /**********************************************************************************************************\
  11. * 实例:
  12. * 小孩子吃饭,经常会闹别扭,在吃饭的前后可能会要求这要求那的(很难搞),
  13. * 所以针对小孩吃饭时这个特别的需求,我们使用Decorator模式来适应这个变化
  14. \**********************************************************************************************************/

  15. #include <iostream>
  16. using namespace std;


  17. // 定义基本接口类,设计模式的通用手法了
  18. class CChildComponent
  19. {
  20. public:
  21.         // 小孩吃饭
  22.         virtual void Eat() = 0;
  23. };

  24. class CChild: public CChildComponent
  25. {
  26. public:
  27.         
  28.         virtual void Eat()
  29.         {
  30.                 cout << "我吃饭了。" << endl;
  31.         }
  32. };

  33. // 如果小孩想在吃饭前先吃个苹果,加个修饰类,这个类和小孩类派生于相同父类
  34. class CDecorator: public CChildComponent
  35. {
  36. public:
  37.         CDecorator(CChildComponent *childCom)
  38.         {
  39.                 _child = childCom;
  40.         }
  41.         virtual void Eat()
  42.         {
  43.         }

  44. protected:
  45.         CChildComponent *_child;
  46. };

  47. // 具体化修饰类
  48. class CChildDecorator: public CDecorator
  49. {
  50. public:
  51.         CChildDecorator(CChildComponent *childCom):CDecorator(childCom)
  52.         {
  53.         }
  54.         virtual void Eat()
  55.         {
  56.                 cout << "我先吃个苹果." << endl;
  57.                 _child->Eat();
  58.         }        
  59. };


  60. // 客户程序
  61. int main()
  62. {
  63.         // 小孩吃饭
  64.         CChild child;
  65.         child.Eat();

  66.         // 这个时候,小孩要先吃个水果再吃饭
  67.         // 所以这个对象的职责增加了
  68.         // 客户端的代码变为:
  69.         CChildDecorator childDec(&child);
  70.         childDec.Eat();

  71.         // 可以看到上面的代码好像是把child给包起来了,它根本就不知道有一个包装类对它进行了包装
  72.         // 满足了OCP原则,这样的话就不怕小孩子闹别扭了,呵呵

  73.         return 0;
  74. }
  75. //output:
  76. //我吃饭了。
  77. //我先吃个苹果.
  78. //我吃饭了。
复制代码
问题:
CChildDecorator(CChildComponent *childCom):CDecorator(childCom)
        {
        }
中的:CDecorator(childCom)是什么意思?
应该是初始化列表,但是CDecorator是类啊,不是 CChildDecorator类中的属性。
感谢您的回答~


有网友总结:http://tieba.baidu.com/f?kz=1167962877
这两天一直搞不明白C++继承的构造函数该怎么写。现在经过实验,总结出了一些观点。欢迎大家批评指正。
在继承中,
一,父类没有写出构造函数,
子类的构造函数可以写成“任何”形式而不用顾及父类的构造函数。
例如:父类为CA,子类为CB,父类中没有写出任何构造函数,则子类中可以不写构造函数,或者构造函数可以写成以下几种:
CB(){};
CB():CA(){};
CB(int a, int b){};
CB(int a, int b):CA(){};
这几种形式都可以。即完全忽略父类的构造函数。
二,父类只写出了一个无参构造函数。
则子类可以不写构造函数,或者写成以下几种。
CB(){};
CB():CA(){};
CB(int a, int b){};
CB(int a, int b):CA(){};
即当父类只写出一个无参构造函数或者没有写构造函数效果是一样的。
三,父类只写出了一个有参构造函数
此时,子类应该“标准”地写出构造函数,例如
CA(int a, int b){};
CB(int a, int b):CA(a,b){};
或者:
CA(int a, int b){};
CB(int a, int b ,int c):CA(a,b){};
四,父类有多个有参构造函数,
此时,子类最少实现一个父类的构造函数即可。
五,父类有多个有参函数和一个无参构造函数。
此时,子类只需实现一个父类的构造函数即可,不管子类实现的是有参构造函数还是无参构造函数。
这时候应该注意,即使子类写成CB(){};也是正确的,说明父类的无参构造函数可以忽略。甚至写成CB(int a, int b){};也是正确的。
总结以上几条可以归纳出C++子类继承父类时构造函数的写法的规律为:
1,当父类有显式写出的构造函数时,子类最低限度的实现父类中的一个。
2,当父类没有显式写出构造函数时,子类可以不写构造函数或者“自由”书写构造函数。
更为普遍的规律总结如下:子类的构造函数以最少满足父类的一个构造函数为准。

我犯错的原因:
1)C++基础没有学好。
2)java类的初始化过程:
初始化的实际过程是这样的:
        (1) 在采取其他任何操作之前,为对象分配的存储空间初始化成二进制零。
        (2) 就象前面叙述的那样,调用基础类构建器。此时,被覆盖的draw()方法会得到调用(的确是在RoundGlyph 构建器调用之前),此时会发现radius 的值为0,这是由于步骤(1)造成的。
        (3) 按照原先声明的顺序调用成员初始化代码。
        (4) 调用衍生类构建器的主体。
  1.     package polymorphism;

  2.     //: polymorphism/PolyConstructors.java
  3.     // Constructors and polymorphism
  4.     // don't produce what you might expect.
  5.     import static net.mindview.util.Print.*;

  6.     class Glyph {
  7.       void draw() { print("Glyph.draw()"); }
  8.       Glyph() {
  9.         print("Glyph() before draw()");
  10.         draw();
  11.         print("Glyph() after draw()");
  12.       }
  13.     }   

  14.     class RoundGlyph extends Glyph {
  15.       private int radius = 1;
  16.       RoundGlyph(int r) {
  17.         radius = r;
  18.         print("RoundGlyph.RoundGlyph(), radius = " + radius);
  19.       }
  20.       void draw() {
  21.         print("RoundGlyph.draw(), radius = " + radius);
  22.       }
  23.     }   

  24.     public class PolyConstructors {
  25.       public static void main(String[] args) {
  26.         new RoundGlyph(5);
  27.       }
  28.     } /* Output:
  29.     Glyph() before draw()
  30.     RoundGlyph.draw(), radius = 0
  31.     Glyph() after draw()
  32.     RoundGlyph.RoundGlyph(), radius = 5
  33.     */
复制代码

论坛徽章:
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
2 [报告]
发表于 2012-09-19 22:05 |只看该作者
构造基类, 大哥.

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
3 [报告]
发表于 2012-09-19 22:17 |只看该作者
别急着看设计模式,会中毒,真的

论坛徽章:
0
4 [报告]
发表于 2012-09-19 22:25 |只看该作者
回复 2# linux_c_py_php

哦,哈哈~
可以写成这样吗?:
    CChildDecorator(CChildComponent *childCom)
        {
        }

论坛徽章:
0
5 [报告]
发表于 2012-09-19 22:26 |只看该作者
回复 3# windoze


    反正都中了,还好我没有安装杀毒软件。大脑检测不出有病毒。
哇咔咔!

论坛徽章:
0
6 [报告]
发表于 2012-09-19 22:42 |只看该作者
看来我会死的很难看,就C++都很晕了。
现在还把Java给搞进去了~~~~~~~~
丢脸了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP