C++面向对象编程

封装:1.抽象出数据成员、成员函数

2.访问控制,类本身1)private 外界不可见,不能直接访问2)外界不可见,不能直接访问;子类可以访问protected3)public外界可以直接访问

继承:

继承访问控制:

1.不能直接拿父亲的私房钱:派生类不能访问基类的私有成员
2. 可以问父亲要钱:通过protected/public的成员函数
3. 儿子总是比外人亲:派生类可以访问父类的protected成员,其他代码不可以

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Father{
 8 private:
 9     int money;
10 protected:
11     int room_key;
12 public:
13     void it_skill(void)
14     {
15         cout<<"father's it skill"<<endl;
16     }
17     int getMoney(void)
18     {
19         return money;
20     }
21 
22     void setMoney(int money)
23     {
24         this->money = money;
25     }
26 
27 };
28 class Son : public Father{
29 private:
30     int toy;
31 public:
32     void play_game(void)
33     {
34         int m;
35         /*money -= 1;
36         *错:不能直接拿父亲的私房钱
37         *但是可以问他要
38         */
39         cout<<"son play game"<<endl;
40         m = getMoney();
41         m -- ;
42         setMoney(m);
43         /*外人不能拿父亲的房间钥匙
44         *但是儿子可以
45         *
46         */
47         room_key = 1;
48     }
49 };
50 int main(int argc,char **argv)
51 {
52     Son s;
53     s.setMoney(10);
54     cout<<s.getMoney()<<endl;
55 
56     s.it_skill();
57     s.play_game();
58     return 0;
59 }
View Code

1.无论哪种继承方式,在派生类内部使用父类时并无差别
2. 不同的继承方式,会影响这两方面:外部代码对派生类的使用、派生类的子类

  1 #include <iostream>
  2 #include <string.h>
  3 #include <unistd.h>
  4 
  5 using namespace std;
  6 
  7 class Father{
  8 private:
  9     int money;
 10 protected:
 11     int room_key;
 12 public:
 13     int address;
 14     void it_skill(void)
 15     {
 16         cout<<"father's it skill"<<endl;
 17     }
 18     int getMoney(void)
 19     {
 20         return money;
 21     }
 22 
 23     void setMoney(int money)
 24     {
 25         this->money = money;
 26     }
 27 
 28 };
 29 class Son_pub : public Father{
 30 private:
 31     int toy;
 32 public:
 33     using Father::room_key;
 34     void play_game(void)
 35     {
 36         int m;
 37         /*money -= 1;
 38         *错:不能直接拿父亲的私房钱
 39         *但是可以问他要
 40         */
 41         cout<<"son play game"<<endl;
 42         m = getMoney();
 43         m -- ;
 44         setMoney(m);
 45         /*外人不能拿父亲的房间钥匙
 46         *但是儿子可以
 47         *
 48         */
 49         room_key = 1;
 50     }
 51 };
 52 
 53 class Son_pro : protected Father{
 54 private:
 55     int toy;
 56 public:
 57     using Father::room_key;
 58     void play_game(void)
 59     {
 60         int m;
 61         /*money -= 1;
 62         *错:不能直接拿父亲的私房钱
 63         *但是可以问他要
 64         */
 65         cout<<"son play game"<<endl;
 66         m = getMoney();
 67         m -- ;
 68         setMoney(m);
 69         /*外人不能拿父亲的房间钥匙
 70         *但是儿子可以
 71         *
 72         */
 73         room_key = 1;
 74     }
 75 };
 76 
 77 class Son_pri : private Father{
 78 private:
 79     int toy;
 80 public:
 81     
 82     void play_game(void)
 83     {
 84         int m;
 85         /*money -= 1;
 86         *错:不能直接拿父亲的私房钱
 87         *但是可以问他要
 88         */
 89         cout<<"son play game"<<endl;
 90         m = getMoney();
 91         m -- ;
 92         setMoney(m);
 93         /*外人不能拿父亲的房间钥匙
 94         *但是儿子可以
 95         *
 96         */
 97         room_key = 1;
 98     }
 99 };
100 
101 class Grandson_pub : public Son_pub{
102 public:
103     void test(void)
104     {
105         room_key = 1;
106         address    = 2;
107     }
108 
109 
110 };
111 
112 class Grandson_pro:public Son_pro{
113 public:
114     void test (void)
115     {
116         room_key = 1;
117         address    = 2;
118     }
119 
120 };
121 
122 class Grandson_pri:public Son_pri{
123 public:
124     void test(void)
125     {
126         //room_key = 1;
127         //address    = 2;
128     }
129 
130 
131 };
132 
133 int main(int argc,char **argv)
134 {
135     Son_pub s_pub;
136     Son_pro s_pro;
137     Son_pri s_pri;
138 
139 
140     s_pub.play_game();
141     s_pro.play_game();
142     s_pri.play_game();
143 
144     s_pub.it_skill();
145     //s_pro.it_skill();//error次在s_pro中把Father的it_skill()函数由public改为了protected
146     //s_pri.it_skill();//error次在s_pri中把Father的it_skill()函数由public改为了private
147 
148     Grandson_pub gs_pub;
149     Grandson_pro gs_pro;
150 
151     gs_pub.address = 2;
152     //gs_pro.address = 2;  // error
153     
154     return 0;
155 }
View Code

调整访问控制:

儿子继承来的财产,他可以捐给别人,也可以私藏(前提:Son看得见这些财产):
Son可见到的成员,Son可以修改它的权限。private: using Father::getMoney;(Son的子类就是用不了Father中的getMoney()函数)

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Father{
 8 private:
 9     int money;
10 protected:
11     int room_key;
12 public:
13     void it_skill(void)
14     {
15         cout<<"father's it skill"<<endl;
16     }
17     int getMoney(void)
18     {
19         return money;
20     }
21 
22     void setMoney(int money)
23     {
24         this->money = money;
25     }
26 
27 };
28 class Son : public Father{
29 private:
30     int toy;
31 public:
32     using Father::room_key;
33     void play_game(void)
34     {
35         int m;
36         /*money -= 1;
37         *错:不能直接拿父亲的私房钱
38         *但是可以问他要
39         */
40         cout<<"son play game"<<endl;
41         m = getMoney();
42         m -- ;
43         setMoney(m);
44         /*外人不能拿父亲的房间钥匙
45         *但是儿子可以
46         *
47         */
48         room_key = 1;
49     }
50 };
51 int main(int argc,char **argv)
52 {
53     Son s;
54     s.setMoney(10);
55     cout<<s.getMoney()<<endl;
56 
57     s.it_skill();
58     s.play_game();
59     s.room_key = 1;//因为在Son中改变了room_key的权限,所以可以访问
60     return 0;
61 }
View Code
  1 #include <iostream>
  2 #include <string.h>
  3 #include <unistd.h>
  4 
  5 using namespace std;
  6 
  7 class Father{
  8 private:
  9     int money;
 10 protected:
 11     int room_key;
 12 public:
 13     void it_skill(void)
 14     {
 15         cout<<"father's it skill"<<endl;
 16     }
 17     int getMoney(void)
 18     {
 19         return money;
 20     }
 21 
 22     void setMoney(int money)
 23     {
 24         this->money = money;
 25     }
 26 
 27 };
 28 class Son_pub : public Father{
 29 private:
 30     int toy;
 31 public:
 32     using Father::room_key;
 33     void play_game(void)
 34     {
 35         int m;
 36         /*money -= 1;
 37         *错:不能直接拿父亲的私房钱
 38         *但是可以问他要
 39         */
 40         cout<<"son play game"<<endl;
 41         m = getMoney();
 42         m -- ;
 43         setMoney(m);
 44         /*外人不能拿父亲的房间钥匙
 45         *但是儿子可以
 46         *
 47         */
 48         room_key = 1;
 49     }
 50 };
 51 
 52 class Son_pro : protected Father{
 53 private:
 54     int toy;
 55 public:
 56     using Father::room_key;
 57     void play_game(void)
 58     {
 59         int m;
 60         /*money -= 1;
 61         *错:不能直接拿父亲的私房钱
 62         *但是可以问他要
 63         */
 64         cout<<"son play game"<<endl;
 65         m = getMoney();
 66         m -- ;
 67         setMoney(m);
 68         /*外人不能拿父亲的房间钥匙
 69         *但是儿子可以
 70         *
 71         */
 72         room_key = 1;
 73     }
 74 };
 75 
 76 class Son_pri : private Father{
 77 private:
 78     int toy;
 79 public:
 80     using Father::room_key;
 81     void play_game(void)
 82     {
 83         int m;
 84         /*money -= 1;
 85         *错:不能直接拿父亲的私房钱
 86         *但是可以问他要
 87         */
 88         cout<<"son play game"<<endl;
 89         m = getMoney();
 90         m -- ;
 91         setMoney(m);
 92         /*外人不能拿父亲的房间钥匙
 93         *但是儿子可以
 94         *
 95         */
 96         room_key = 1;
 97     }
 98 };
 99 
100 int main(int argc,char **argv)
101 {
102     Son_pub s_pub;
103     Son_pro s_pro;
104     Son_pri s_pri;
105 
106 
107     s_pub.play_game();
108     s_pro.play_game();
109     s_pri.play_game();
110 
111     s_pub.it_skill();
112     //s_pro.it_skill();//error次在s_pro中把Father的it_skill()函数由public改为了protected
113     //s_pri.it_skill();//error次在s_pri中把Father的it_skill()函数由public改为了private
114     return 0;
115 }
View Code

此为验证基类成员在派生类中的访问控制属性

复写基类中的函数,此时子类就会调用自己的与父类中相同名字的函数

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Father{
 8 private:
 9     int money;
10 protected:
11     int room_key;
12 public:
13     int address;
14     void it_skill(void)
15     {
16         cout<<"father's it skill"<<endl;
17     }
18     int getMoney(void)
19     {
20         return money;
21     }
22 
23     void setMoney(int money)
24     {
25         this->money = money;
26     }
27 
28 };
29 class Son : public Father{
30 private:
31     int toy;
32 public:
33     using Father::room_key;
34     void play_game(void)
35     {
36         int m;
37         /*money -= 1;
38         *错:不能直接拿父亲的私房钱
39         *但是可以问他要
40         */
41         cout<<"son play game"<<endl;
42         m = getMoney();
43         m -- ;
44         setMoney(m);
45         /*外人不能拿父亲的房间钥匙
46         *但是儿子可以
47         *
48         */
49         room_key = 1;
50     }
51     void it_skill(void)//复写了父类中的相同名字的函数
52     {
53         cout<<"son's it skill"<<endl;
54     }
55 };
56 int main(int argc,char **argv)
57 {
58     Son s;
59 
60     s.setMoney(10);
61     cout<<s.getMoney()<<endl;
62 
63     s.it_skill();
64     s.play_game();
65 
66     s.room_key = 1;
67     
68     return 0;
69 }
View Code

派生类对象s的空间 :

money 基类部分 (Father)

toy 派生部分 (Son)

  1 #include <iostream>
  2 #include <string.h>
  3 #include <unistd.h>
  4 
  5 using namespace std;
  6 
  7 class person{
  8 private:
  9     char *name;
 10     int age;
 11 public:
 12     int address;
 13     person()
 14     {
 15         name = NULL;
 16         
 17     }
 18     person (char*name)
 19     {
 20         this->name = new char[strlen(name)+1];
 21         strcpy(this->name,name);
 22     }
 23     person(char *name, int age) 
 24     {
 25         cout <<"person(char*, int), name = "<<name<<", age= "<<age<<endl;
 26         this->age = age;
 27 
 28         this->name = new char[strlen(name) + 1];
 29         strcpy(this->name, name);
 30     }
 31 
 32     person(person &per) 
 33     {
 34         cout <<"person(person &)"<<endl;
 35         this->age = per.age;
 36 
 37         this->name = new char[strlen(per.name) + 1];
 38         strcpy(this->name, per.name);
 39     }
 40 
 41     ~person()
 42     {
 43         cout << "~person()"<<endl;
 44         if (this->name) {
 45             cout << "name = "<<name<<endl;
 46             delete this->name;
 47         }
 48     }
 49 
 50     void setName(char *name)
 51     {
 52         if (this->name) {
 53             delete this->name;
 54         }
 55         this->name = new char[strlen(name) + 1];
 56         strcpy(this->name, name);
 57     }
 58     int setAge(int a)
 59     {
 60         if (a < 0 || a > 150)
 61         {
 62             age = 0;
 63             return -1;
 64         }
 65         age = a;
 66         return 0;
 67     }
 68     void printInfo(void)
 69     {
 70         cout<<"name = "<<name<<", age = "<<age<<endl;
 71     }
 72 
 73 };
 74 class Student : public person {
 75 private:
 76     int grade;
 77     void setGrade(int grade) {this->grade = grade;}
 78     int getGrade(void) {return grade;}
 79 public:
 80     void printInfo(void)//复写
 81     {
 82         cout<<"Student ";
 83         person::printInfo();
 84     }
 85 };
 86 void test_func(person &p)//调用的person中的部分
 87 {
 88     p.printInfo();
 89 }
 90 int main(int argc, char **argv)
 91 {
 92     person p("lisi", 16);
 93 
 94     Student s;
 95     s.setName("zhangsan");
 96     s.setAge(16);
 97 
 98     test_func(p);
 99     test_func(s); /* person &p =   s里面的person部分;
100                    * p引用的是"s里面的person部分"
101                    *相当于是只是操作派生类student中继承的person部分的内容
102                    */
103     s.printInfo();
104 
105     return 0;
106 }
View Code

多继承:一个派生类可以有多个基类

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Sofa{
 8 public:
 9     void watchTV(void)
10     {
11         cout<<"watch TV"<<endl;
12     }
13 
14 };
15 class Bed{
16 public:
17     void sleep(void)
18     {
19         cout<<"sleep"<<endl;
20     }
21 
22 
23 };
24 class Sofabed : public Sofa,public Bed{
25 
26 
27 };
28 
29 int main(int argc,char **argv)
30 {
31     Sofabed s;
32     s.watchTV();
33     s.sleep();
34     return 0;
35 }
View Code

问题:二义性

class Sofa里有weight, class Bed里也有weight
那么Sofabed就有2个weight,
既别扭,也有二义性──用哪个weight ?

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Sofa{
 8 private:
 9     int weight;
10 public:
11     void watchTV(void)
12     {
13         cout<<"watch TV"<<endl;
14     }
15     void setWeight(int weight)
16     {
17         this->weight = weight;
18     }
19     int getWeight(void)const
20     {
21         return weight;
22     }
23 
24 };
25 class Bed{
26 private:
27     int weight;
28 public:
29     void sleep(void)
30     {
31         cout<<"sleep"<<endl;
32     }
33     void setWeight(int weight)
34     {
35         this->weight = weight;
36     }
37     int getWeight(void)const
38     {
39         return weight;
40     }
41 
42 
43 };
44 class Sofabed : public Sofa,public Bed{
45 
46 
47 };
48 
49 int main(int argc,char **argv)
50 {
51     Sofabed s;
52     s.watchTV();
53     s.sleep();
54 
55     //s.setWeight(100);//出现二义性,不知道调用的是哪个类中setWeight()函数
56     s.Sofa::setWeight(100);//解决方法
57     return 0;
58 }
View Code

解决方法:虚基类使得:多个类派生出的对象只继承一个基类对象,即:Sofabed的基类Sofa, Bed共享一个Furniture对象

1.从Sofa, Bed中取出公共特性,创建新类Furniture: 它含有weight

2.Sofa, Bed虚拟继承Furniture

3.Sofabed多重继承Sofa, Bed

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Furniture{
 8 private:
 9     int weight;
10 public:
11     void setWeight(int weight)
12     {
13         this->weight = weight;
14     }
15     int getWeight(void)const
16     {
17         return weight;
18     }
19 
20 };
21 
22 class Sofa : virtual public Furniture{
23 private:
24     int a;
25 public:
26     void watchTV(void)
27     {
28         cout<<"watch TV"<<endl;
29     }
30 
31 };
32 class Bed : virtual public Furniture{
33 private:
34     int b;
35 public:
36     void sleep(void)
37     {
38         cout<<"sleep"<<endl;
39     }
40 };
41 class Sofabed : public Sofa,public Bed{
42 private:
43     int c;
44 
45 };
46 
47 int main(int argc,char **argv)
48 {
49     Sofabed s;
50     s.watchTV();
51     s.sleep();
52 
53     s.setWeight(100);
54     return 0;
55 }
View Code

构造顺序:

1. 虚拟基类构造函数:按继承顺序,只执行一次
2. 非虚拟基类构造函数:按继承顺序
3. 类的对象成员(按声明的顺序)
4. 类自己的构造函数

这个即为构造顺序

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Furniture{
 8 private:
 9     int weight;
10 public:
11     void setWeight(int weight)
12     {
13         this->weight = weight;
14     }
15     int getWeight(void)const
16     {
17         return weight;
18     }
19     Furniture()
20     {
21         cout<<"Furniture"<<endl;
22     }
23 
24 };
25 
26 class Vertification3C{
27 public:
28     Vertification3C(){cout<<"Verfification3C()"<<endl;}
29 
30 };
31 
32 class Sofa : virtual public Furniture,virtual public Vertification3C{
33 private:
34     int a;
35 public:
36     void watchTV(void)
37     {
38         cout<<"watch TV"<<endl;
39     }
40     Sofa(){cout<<"Sofa()"<<endl;}
41 
42 };
43 class Bed : virtual public Furniture{
44 private:
45     int b;
46 public:
47     void sleep(void)
48     {
49         cout<<"sleep"<<endl;
50     }
51     Bed(){cout<<"Bed()"<<endl;}
52 };
53 class Sofabed : public Sofa,public Bed{
54 private:
55     int c;
56 public:
57     Sofabed()
58         {
59             cout<<"Sofabed()"<<endl;
60         }
61 
62 };
63 
64 class LeftRightCom{
65 public:
66     LeftRightCom(){cout<<"LeftRightCom"<<endl;}
67 };
68 class Data{
69 public:
70     Data(){cout<<"Data()"<<endl;}
71 };
72 class Type{
73 public:
74     Type(){cout<<"Type()"<<endl;}
75 };
76 class LeftRightSofabed : public Sofabed, public LeftRightCom {
77 private:
78     Data date;
79     Type type;
80 
81 public:
82     LeftRightSofabed() { cout <<"LeftRightSofabed()"<<endl; }
83     
84 };
85 
86 int main(int argc,char **argv)
87 {
88     LeftRightSofabed s;
89     return 0;
90 }
View Code

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Furniture{
 8 private:
 9     int weight;
10 public:
11     void setWeight(int weight)
12     {
13         this->weight = weight;
14     }
15     int getWeight(void)const
16     {
17         return weight;
18     }
19     Furniture()
20     {
21         cout<<"Furniture()"<<endl;
22     }
23 
24 };
25 
26 class Vertification3C{
27 public:
28     Vertification3C(){cout<<"Verfification3C()"<<endl;}
29 
30 };
31 
32 class Sofa : virtual public Furniture,virtual public Vertification3C{
33 private:
34     int a;
35 public:
36     void watchTV(void)
37     {
38         cout<<"watch TV"<<endl;
39     }
40     Sofa(){cout<<"Sofa()"<<endl;}
41 
42 };
43 class Bed : virtual public Furniture{
44 private:
45     int b;
46 public:
47     void sleep(void)
48     {
49         cout<<"sleep"<<endl;
50     }
51     Bed(){cout<<"Bed()"<<endl;}
52 };
53 class Sofabed : public Sofa,public Bed{
54 private:
55     int c;
56 public:
57     Sofabed()
58         {
59             cout<<"Sofabed()"<<endl;
60         }
61 
62 };
63 
64 class LeftRightCom{
65 public:
66     LeftRightCom(){cout<<"LeftRightCom()"<<endl;}
67 };
68 class Data{
69 public:
70     Data(){cout<<"Data()"<<endl;}
71 };
72 class Type{
73 public:
74     Type(){cout<<"Type()"<<endl;}
75 };
76 class LeftRightSofabed : public Sofabed,virtual public LeftRightCom {
77 private:
78     Data date;
79     Type type;
80 
81 public:
82     LeftRightSofabed() { cout <<"LeftRightSofabed()"<<endl; }
83     
84 };
85 
86 int main(int argc,char **argv)
87 {
88     LeftRightSofabed s;
89     return 0;
90 }
View Code

 1 #include <iostream>
 2 #include <string.h>
 3 #include <unistd.h>
 4 
 5 using namespace std;
 6 
 7 class Furniture{
 8 private:
 9     int weight;
10 public:
11     void setWeight(int weight)
12     {
13         this->weight = weight;
14     }
15     int getWeight(void)const
16     {
17         return weight;
18     }
19     Furniture()
20     {
21         cout<<"Furniture()"<<endl;
22     }
23 
24 };
25 
26 class Vertification3C{
27 public:
28     Vertification3C(){cout<<"Verfification3C()"<<endl;}
29 
30 };
31 
32 class Sofa : virtual public Furniture,virtual public Vertification3C{
33 private:
34     int a;
35 public:
36     void watchTV(void)
37     {
38         cout<<"watch TV"<<endl;
39     }
40     Sofa(){cout<<"Sofa()"<<endl;}
41 
42 };
43 class Bed : virtual public Furniture,virtual Vertification3C{
44 private:
45     int b;
46 public:
47     void sleep(void)
48     {
49         cout<<"sleep"<<endl;
50     }
51     Bed(){cout<<"Bed()"<<endl;}
52 };
53 class Sofabed : public Sofa,public Bed{
54 private:
55     int c;
56 public:
57     Sofabed()
58         {
59             cout<<"Sofabed()"<<endl;
60         }
61     Sofabed(char *abc){cout<<"Sofabed(char *abc)"<<endl;}
62 
63 };
64 
65 class LeftRightCom{
66 public:
67     LeftRightCom(){cout<<"LeftRightCom()"<<endl;}
68     LeftRightCom(char *abc) { cout <<"LeftRightCom(char *abc)"<<endl; }
69 };
70 class Data{
71 public:
72     Data(){cout<<"Data()"<<endl;}
73     Data(char *abc) { cout <<"Date(char *abc)"<<endl; }
74 };
75 class Type{
76 public:
77     Type(){cout<<"Type()"<<endl;}
78     Type(char *abc) { cout <<"Type(char *abc)"<<endl; }
79 };
80 class LeftRightSofabed : public Sofabed,virtual public LeftRightCom {
81 private:
82     Data date;
83     Type type;
84 
85 public:
86     LeftRightSofabed() { cout <<"LeftRightSofabed()"<<endl; }
87     LeftRightSofabed(char *str1, char *str2, char *str3) : Sofabed(str1), LeftRightCom(str2), date(str3) { cout <<"LeftRightSofabed()"<<endl; }
88     
89 };
90 
91 int main(int argc,char **argv)
92 {
93     LeftRightSofabed s("abc", "2343", "yyy");;
94     return 0;
95 }
View Code

猜你喜欢

转载自www.cnblogs.com/yekongdebeijixing/p/12099448.html