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的主要内容,如果未能解决你的问题,请参考以下文章

C++第四天笔记2016年01月29日(周五)A.M

C语言第五天笔记2016年01月18日(周一)P.M

C语言第五天笔记2016年01月18日(周一)A.M

C语言第九天笔记2016年01月25日(周一)P.M

OC第七天笔记2016年03月21日(周一)P.M

OC第六天笔记2016年03月21日(周一)A.M