- 论坛徽章:
- 0
|
本帖最后由 时间看来 于 2012-09-19 22:36 编辑
本来我的C++基础知识都掌握得不好。
最近却尝试着看一些设计模式东西,差不多以《[设计模式:可复用面向对象软件的基础].(Design.Patterns:Elements.of.Reusable.Object-Oriented.Software).Erich.Gamma》为参考,但是使用的代码示例却不是这本书的。在网上找了一些示例:- /**********************************************************************************************************\
- * 作者:一雨田(http://blog.csdn.net/dylgsy/)
- *
- * Decorator模式:
- * 动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类
- * 更为灵活。
- * 由于Decorator模式仅从外部改变组件,因此组件无需对它的装饰有任何了解;也就是说,
- * 这些装饰对该组件是透明的。
- \**********************************************************************************************************/
- /**********************************************************************************************************\
- * 实例:
- * 小孩子吃饭,经常会闹别扭,在吃饭的前后可能会要求这要求那的(很难搞),
- * 所以针对小孩吃饭时这个特别的需求,我们使用Decorator模式来适应这个变化
- \**********************************************************************************************************/
- #include <iostream>
- using namespace std;
- // 定义基本接口类,设计模式的通用手法了
- class CChildComponent
- {
- public:
- // 小孩吃饭
- virtual void Eat() = 0;
- };
- class CChild: public CChildComponent
- {
- public:
-
- virtual void Eat()
- {
- cout << "我吃饭了。" << endl;
- }
- };
- // 如果小孩想在吃饭前先吃个苹果,加个修饰类,这个类和小孩类派生于相同父类
- class CDecorator: public CChildComponent
- {
- public:
- CDecorator(CChildComponent *childCom)
- {
- _child = childCom;
- }
- virtual void Eat()
- {
- }
- protected:
- CChildComponent *_child;
- };
- // 具体化修饰类
- class CChildDecorator: public CDecorator
- {
- public:
- CChildDecorator(CChildComponent *childCom):CDecorator(childCom)
- {
- }
- virtual void Eat()
- {
- cout << "我先吃个苹果." << endl;
- _child->Eat();
- }
- };
- // 客户程序
- int main()
- {
- // 小孩吃饭
- CChild child;
- child.Eat();
- // 这个时候,小孩要先吃个水果再吃饭
- // 所以这个对象的职责增加了
- // 客户端的代码变为:
- CChildDecorator childDec(&child);
- childDec.Eat();
- // 可以看到上面的代码好像是把child给包起来了,它根本就不知道有一个包装类对它进行了包装
- // 满足了OCP原则,这样的话就不怕小孩子闹别扭了,呵呵
- return 0;
- }
- //output:
- //我吃饭了。
- //我先吃个苹果.
- //我吃饭了。
复制代码 问题:
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) 调用衍生类构建器的主体。- package polymorphism;
- //: polymorphism/PolyConstructors.java
- // Constructors and polymorphism
- // don't produce what you might expect.
- import static net.mindview.util.Print.*;
- class Glyph {
- void draw() { print("Glyph.draw()"); }
- Glyph() {
- print("Glyph() before draw()");
- draw();
- print("Glyph() after draw()");
- }
- }
- class RoundGlyph extends Glyph {
- private int radius = 1;
- RoundGlyph(int r) {
- radius = r;
- print("RoundGlyph.RoundGlyph(), radius = " + radius);
- }
- void draw() {
- print("RoundGlyph.draw(), radius = " + radius);
- }
- }
- public class PolyConstructors {
- public static void main(String[] args) {
- new RoundGlyph(5);
- }
- } /* Output:
- Glyph() before draw()
- RoundGlyph.draw(), radius = 0
- Glyph() after draw()
- RoundGlyph.RoundGlyph(), radius = 5
- */
复制代码 |
|