树欲静而风不止btpka3.blog.chinaunix.net
btpka3
全部博文(135)
2012年(29)
2011年(41)
2010年(26)
2009年(12)
2008年(9)
2007年(12)
2006年(6)
zhangdiv
hcu5555
jayflygo
韩仪ails
沐依静
jiangzhe
cheercho
shanggua
609854
lzyunv
格伯纳
yuanzh78
Otokaze
masterro
bcskydri
tyshan
wangyinh
oyjyb
分类: C/C++
2006-10-27 16:47:21
/* * Test.cpp * 用于温习已学过的C++关于类继承, 多态的知识, 做备注用. * btpka3@163.com * 2006/9/1 */ #include using std::cout; using std::endl; /** * Node */ class Node{ //抽象类, 不能够被实例化 public: void toString() const{ /* const 在函数参数列表和定义块开始之间加入const可以使声明为const的对象实例调用该 函数, 即若Node不是抽象类的话, 如下声明: const Node anode; 则anode可以调用 print函数, 但是必须保证 该函数李不能修改anode对象, 否则运行时错误. */ cout << "Object : Node" << endl; return; }; virtual void print() const{ //虚拟函数 /* vitrual 用virtual修饰的函数是虚拟函数, 它使有继承关系的类各自实现各自的函数版本, 然后在类实例调用时动态绑定需要调用的函数. */ cout << "print() in Node" << endl; return; }; virtual void print_pv() const=0; //纯虚函数 /* =0 在声明时初始化为0的虚拟函数就是纯虚函数, 纯虚寒士使得类成为抽象类, 纯虚函数 不具有实现细节, 所有子类必须实现. */ }; /** * Father */ class Father : public Node{ private: char name[20]; int age; char sex; public: Father(){ //由于C++类中构造函数只要提供构造函数, 就不再提供默认无参构造函数 //所以, 一般最好提供一个默认无参构造函数, 否则必须在子类的构造函 //数后用冒号指明要调用父类的哪一个构造函数, 或者子类的构造函数的 //参数列表类型与父类的一致, strcpy( name, "NO_NAME_FATHER"); age = 0; sex = 'F'; cout << "CONSTRUCTOR: Father, No args : " << name << endl; }; Father(char* arg_name, int arg_age, char arg_sex){ //cout <<"iii"<toString(); pNode->print(); pNode->print_pv(); cout << endl << endl << "display father --- pFather" << endl; pFather = & fff; pFather->toString(); pFather->print(); pFather->print_pv(); cout << endl << "不能够将子类指针指向父类对象: pChild = & fff;" << endl; //pChild = & fff; //编译器错误: invalid conversion from `Father*' to `Child*' //display child cout << endl << endl << "display child --- object" << endl; ccc.toString(); ccc.print(); ccc.print_pv(); //无论子类用哪种祖先类的指针来调用, 纯虚函数始终都是调用子类自己版本的函数 //而普通函数的虚拟函数随着指针类型的不同而调用各自版本的函数 cout << endl << endl << "display child --- pNode" << endl; pNode = & ccc; pNode->toString(); pNode->print(); pNode->print_pv(); //尝试调用Node版本的print() //((Node)*pNode).print(); //编译器错误: cannot allocate an object of type `Node' cout << "pNode 尝试调用Fahter的toString(), print(), print_PV() : " << endl; cout << "\t - (dynamic_cast(pNode))->" << endl; //非虚函数, 根据指针类型调用Father类版本 (dynamic_cast(pNode))->toString(); //虚函数, 动态绑定, 调用Child类版本, (dynamic_cast(pNode))->print(); //但是若再将对象强制转换为Father类, 则可以, 不过会调用拷贝构造函数, //最后调用析构函数 //虚函数, 动态绑定, 调用Child类版本 (dynamic_cast(pNode))->print_pv(); cout << "\t - ((Father)*((Father* )pNode))." << endl; //((Father)*pNode).toString(); //Error; //若pNode类型为Node*则编译器错误, no matching function for call to `Father::Father(Node&)' //所以必须在 Father类里提供构造函数 Father::Father(Node&) //*pNode被认为是Node类型, 但是如下先转换指针类型, 再转换则可以 //强制类型转换, 调用默认拷贝构造函数, ((Father)*((Father* )pNode)).toString(); //然后调用Father类版本的函数, 最后调用析构函数; //同上, 调用Father版本, 虽然是虚拟函数 ((Father)*((Father* )pNode)).print(); ((Father)*((Father* )pNode)).print_pv(); cout << endl << endl << "display child --- pFather" << endl; pFather = & ccc; pFather->toString(); pFather->print(); pFather->print_pv(); cout << endl << endl << "display child --- pChild" << endl; pChild = & ccc; pChild->toString(); pChild->print(); pChild->print_pv(); cout << endl << endl << "" << endl; //system("pause"); //析构的打印显示只有在命令行方式下运行该文件编译后的exe文件才能看到 }; //http://www.cublog.cn/opera/showart.php?blogid=4251&id=127354 //C++的类型转换符有四个reinterpret_cast, static_cast, const_cast, dynamic_cast. //const_cast比较简单,它的作用是除去变量的const或者novolatile属性。 //static_cast 同C, 都是强制类型转换, 但是有更多限制 //reinterpret_cast重新解释类型的定义。是在运行时操作的。 //dynamic_cast,它被用于安全地沿着类的继承关系向下进行类型转换 // dynamic_cast(EXPRESSION)); // 比如: 子类指针 XXX = dynamic_cast<子类指针>(父类指针); 若父类指针指向的 实际是给定的子类 // 则XXX为对象地址, 否则为0; //注意: 砖换的是指针的类型!!! /* 运行结果: build father CONSTRUCTOR: Father : FFFF build child CONSTRUCTOR: Father : MMMM CONSTRUCTOR: Child : CCCC build child, More args CONSTRUCTOR: Father, No args : NO_NAME_FATHER CONSTRUCTOR: Child, No args : NO_NAME_CHILD display father --- object Object : Father : FFFF NO CONST Father: FFFF name: FFFF age : 88 sex : F print_pv() in Father : FFFF display father --- pNode Object : Node Father: FFFF name: FFFF age : 88 sex : F print_pv() in Father : FFFF display father --- pFather Object : Father : FFFF NO CONST Father: FFFF name: FFFF age : 88 sex : F print_pv() in Father : FFFF 不能够将子类指针指向父类对象: pChild = & fff; display child --- object Object : Father : MMMM Object : Child : CCCC Father: MMMM name: MMMM age : 99 sex : M Child : CCCC name: CCCC age : 12.12 sex : F print_pv() in Father : MMMM print_pv() in Child : CCCC display child --- pNode Object : Node Father: MMMM name: MMMM age : 99 sex : M Child : CCCC name: CCCC age : 12.12 sex : F print_pv() in Father : MMMM print_pv() in Child : CCCC pNode 尝试调用Fahter的toString(), print(), print_PV() : - (dynamic_cast(pNode))-> Object : Father : MMMM NO CONST Father: MMMM name: MMMM age : 99 sex : M Child : CCCC name: CCCC age : 12.12 sex : F print_pv() in Father : MMMM print_pv() in Child : CCCC - ((Father)*((Father* )pNode)). Object : Father : MMMM NO CONST DE-CONSTRUCTOR: Father : MMMM Father: MMMM name: MMMM age : 99 sex : M DE-CONSTRUCTOR: Father : MMMM print_pv() in Father : MMMM DE-CONSTRUCTOR: Father : MMMM display child --- pFather Object : Father : MMMM NO CONST Father: MMMM name: MMMM age : 99 sex : M Child : CCCC name: CCCC age : 12.12 sex : F print_pv() in Father : MMMM print_pv() in Child : CCCC display child --- pChild Object : Father : MMMM Object : Child : CCCC Father: MMMM name: MMMM age : 99 sex : M Child : CCCC name: CCCC age : 12.12 sex : F print_pv() in Father : MMMM print_pv() in Child : CCCC DE-CONSTRUCTOR: Child : NO_NAME_CHILD DE-CONSTRUCTOR: Father : NO_NAME_FATHER DE-CONSTRUCTOR: Child : CCCC DE-CONSTRUCTOR: Father : MMMM DE-CONSTRUCTOR: Father : FFFF */
上一篇:prototype.js 关于自定义事件的小结
下一篇:翻译 - hosts.allow的语法
登录 注册