C++第十天笔记2016年02月29日(周一)A.M
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++第十天笔记2016年02月29日(周一)A.M相关的知识,希望对你有一定的参考价值。
1.把子类对象作为父类对象使用:
1.1 前提:继承方式必须公有。
1.2 将子类对象用作父类对象。
1.2.1 将子类对象赋值给父类对象。
1.2.2 将父类引用指向子类对象。(即用派生类对象初始化基类引用)
1 #include <iostream> 2 using namespace std; 3 4 class Base{ 5 public: 6 Base(){} 7 Base(int b):_b(b){} 8 void func(){cout<<"b:"<<_b<<endl;} 9 Base& fun(Base& b); 10 protected: 11 int _b; 12 13 }; 14 class Derived:public Base{ 15 public: 16 Derived(){} 17 Derived(int d,int b):_d(d),Base(b){} 18 void func(); 19 // void func(){cout<<"d:"<<_d<<" b:"<<_b<<endl;} 20 protected: 21 int _d; 22 }; 23 void Derived::func(){cout<<"d:"<<_d<<" b:"<<_b<<endl;} 24 Base& fun(Base& b){Derived* p=new Derived;return *p;} 25 Base* fun(Base* b){Derived* p=new Derived;return b;} 26 27 int main(int argc, const char * argv[]) { 28 29 //---------------------------------------------------------------------------- 30 //---------------------------------------------------------------------------- 31 //1.将派生类对象赋值给基类对象。赋值完成后,等号左边的对象,依然是父类对象。 32 Derived d(4,5); 33 Base b; 34 b=d; 35 d.func(); 36 //---------------------------------------------------------------------------- 37 //---------------------------------------------------------------------------- 38 //2.基类引用指派生类 39 //(1).派生类对象用于初始化基类引用。 40 // Derived d(4,5); 41 // Base& b=d; 42 // b.func(); 43 // d.func(); 44 //---------------------------------------------------------------------------- 45 //---------------------------------------------------------------------------- 46 //(2).派生类对象被传递给一个函数,接受基类对象的引用。 47 // Derived d; 48 // Base& b=fun(d); 49 // delete &b; 50 //---------------------------------------------------------------------------- 51 //---------------------------------------------------------------------------- 52 //(3).派生类从返回类型的函数返回基类引用。 53 // Derived d; 54 // Base& b=fun(d); 55 // delete &b; 56 //---------------------------------------------------------------------------- 57 //---------------------------------------------------------------------------- 58 //3.基类指针指派生类。 59 //(1).派生类对象的地址分配给基类指针。 60 // Derived d(1,4); 61 // Base* b=&d; 62 // d.func(); 63 // b->func(); 64 //---------------------------------------------------------------------------- 65 //---------------------------------------------------------------------------- 66 //(2).派生类指针被分配给基类指针。 67 // Derived d(1,4); 68 // Derived * d2=&d; 69 // Base* b2=d2; 70 // b2->func(); 71 //---------------------------------------------------------------------------- 72 //---------------------------------------------------------------------------- 73 //(3).派生类对象的地址传递给接受基类对象的指针的函数。 74 // Derived d(1,3); 75 // Base* b=fun(&d); 76 // b->func(); 77 // delete b; 78 //---------------------------------------------------------------------------- 79 //---------------------------------------------------------------------------- 80 //当父类指针指向子类对象时,不能通过父类调用子类扩展函数。 81 //另一方面,基类对象不能用作派生类对象。 82 return 0; 83 }
2. 基类指针指向派生类
3. 向下类型转换:将基类的指针或者引用转化为派生类的指针和引用。
实现形式:强转。
目的:通过基类指针或者引用访问到派生类的成员
Point* p=&c;//指针p”指向”的对象”真实身份”为派生类
Point& q=c;//基类引用q”指向”的对象”真实身份”为派生类。
((Circle*)p)->print();
((Circle&)p).print();//向下类需转换
问题:
Point* p=&pp;//pp为基类对象,指针p“指向”的对象“真实身份”基类。((Circle*)p)->print();
有可能出现的问题,输出结果不正确。
向下类型转换不会出现问题:基类指针或者引用“指向”的对象,“真 实身份”为派生类。
1 //#include <iostream> 2 //using namespace std; 3 ////如果一个基类指针指向派生类对象,它可以进行类型转换来访问派生类的成员。这就是所谓的向下转型。然而向下转型是一件危险的做法,因为基类指针可能不实际指向一个对象在派生类,然后程序员任务它是。 4 //class Base{ 5 //public: 6 // Base(){} 7 // Base(int _b):b(_b){} 8 //protected: 9 // int b; 10 //}; 11 //class Derived:public Base{ 12 //public: 13 // Derived(){} 14 // Derived(int _d,int _b):d(_d),Base(_b){} 15 // void func(); 16 //protected: 17 // int d; 18 //}; 19 //void Derived::func(){cout<<"d:"<<d<<" b:"<<b<<endl;} 20 // 21 //int main(int argc, const char * argv[]) { 22 // Derived(3,4); 23 // Base* b=new Derived; 24 // //b->func(); //不可以 25 // ((Derived*)b)->func();//可以 26 // return 0; 27 //} 28 #include <iostream> 29 using namespace std; 30 31 class Base{ 32 public: 33 Base(){} 34 Base(int _b):b(_b){} 35 void func(){cout<<"Base class function..."<<endl;} 36 protected: 37 int b; 38 }; 39 40 class Derived:public Base{ 41 public: 42 Derived(){} 43 Derived(int _d,int _b):d(_d),Base(_b){} 44 void func(){cout<<"Derived class function..."<<endl;} 45 protected: 46 int d; 47 }; 48 49 void foo(Base& b){b.func();}//Base class function... 50 int main(int argc, const char * argv[]) { 51 Derived d; 52 Base b; 53 Base* p=&d; 54 Base& br=d; 55 b=d; 56 b.func();//Base class function... 57 d.func();//Derived class function... 58 p->func();//Base class function... 59 foo(br); 60 br.func();//Base class function... 61 return 0; 62 }
子类构造:
Base声明:
#include <stdio.h> #include "iostream" #include "cstring" using namespace std; class Base{ public: Base(int a=0,char* s=(char*)""):id(a) { if (!s) { name=NULL; }else{ name=new char[strlen(s)+1]; strcpy(name, s); } cout<<"基类默认构造函数"<<endl; } Base(Base& b){ id=b.id; if (!b.name) { delete [] name; name=NULL; } else{ name=new char[strlen(b.name)+1]; strcpy(name, b.name); } cout<<"基类拷贝构造"<<endl; } ~Base(){ if (name!=NULL) { delete [] name; name=NULL; } cout<<"基类析构"<<endl; } Base& operator=(Base&); friend ostream& operator<<(ostream& out,Base&); protected: int id; char* name; };
Base实现:
1 #include "Base.hpp" 2 Base& Base::operator=(Base& b){ 3 if (this!=&b) { 4 id=b.id; 5 delete [] name; 6 if (!b.name) { 7 name=NULL; 8 }else{ 9 name=new char[strlen(b.name)+1]; 10 strcpy(name, b.name); 11 } 12 } 13 cout<<"基类赋值重载"<<endl; 14 return *this; 15 } 16 ostream& operator<<(ostream& out,Base& b){ 17 out<<"Base id:"<<b.id<<endl; 18 return out; 19 }
Derived声明:
1 #include <stdio.h> 2 #include "Base.hpp" 3 #include "cstring" 4 #include "iostream" 5 using namespace std; 6 class Derived:public Base{ 7 public: 8 Derived(int a=0,char* s=(char*)"",float x=0,char* t=(char*)""):Base(a,s),f(x){ 9 if (!t) { 10 label=NULL; 11 }else{ 12 label=new char[strlen(t)+1]; 13 strcpy(label, t); 14 } 15 cout<<"派生类拷贝构造"<<endl; 16 } 17 ~Derived(){ 18 // delete [] label; 19 cout<<"派生类析构"<<endl; 20 } 21 Derived& operator=(Derived&); 22 friend ostream& operator<<(ostream& out,Derived&); 23 private: 24 float f; 25 char* label; 26 };
Derived实现:
1 #include "Derived.hpp" 2 Derived& Derived::operator=(Derived& d){ 3 if (this!=&d) { 4 delete [] label; 5 label=NULL; 6 Base::operator=(d); 7 f=d.f; 8 if (!d.label) { 9 label=NULL; 10 }else{ 11 label=new char[strlen(d.label)+1]; 12 strcpy(label, d.label); 13 } 14 cout<<"派生类赋值重载"<<endl; 15 } 16 return *this; 17 } 18 ostream& operator<<(ostream& out,Derived& d){ 19 out<<(Base&)d; 20 out<<"Derived f:"<<d.f<<endl; 21 out<<"Derived label:"<<d.label<<endl; 22 return out; 23 }
main函数:
1 #include <iostream> 2 #include "Base.hpp" 3 #include "Derived.hpp" 4 using namespace std; 5 6 int main(int argc, const char * argv[]) { 7 8 Derived d1; 9 Derived d2(d1); 10 return 0; 11 }
以上是关于C++第十天笔记2016年02月29日(周一)A.M的主要内容,如果未能解决你的问题,请参考以下文章