C++继承可以是单一继承或多重继承,每一个继承连接可以是public,protected,private也可以是virtual或non-virtual。然后是各个成员函数选项可以是virtual或non-virtual或pure virtual。本文仅仅作出一些关键点的验证。
public继承,例如下:
1 class base
2 {...}
3 class derived:public base
4 {...}
如果这样写,编译器会理解成类型为derived的对象同时也是类型为base的对象,但类型为base的对象不是类型为derived的对象。这点很重要。那么函数形参为base类型适用于derived,形参为derived不适用于base。下面是验证代码,一个参数为base的函数,传入derived应该成功执行,相反,一个参数为derived的函数
1 #include <iostream>
2 #include <stdio.h>
3
4 class base
5 {
6 public:
7 base()
8 :baseName(""),baseData(0)
9 {}
10
11 base(std::string bn,int bd)
12 :baseName(bn),baseData(bd)
13 {}
14
15 std::string getBaseName() const
16 {
17 return baseName;
18 }
19
20 int getBaseData()const
21 {
22 return baseData;
23 }
24
25 private:
26 std::string baseName;
27 int baseData;
28 };
29
30 class derived:public base
31 {
32 public:
33 derived():base(),derivedName("")
34 {}
35 derived(std::string bn,int bd,std::string dn)
36 :base(bn,bd),derivedName(dn)
37 {}
38 std::string getDerivedName() const
39 {
40 return derivedName;
41 }
42 private:
43 std::string derivedName;
44 };
45
46 void show(std::string& info,const base& b)
47 {
48 info.append("Name is ");
49 info.append(b.getBaseName());
50 info.append(", baseData is ");
51 char buffer[10];
52 sprintf(buffer,"%d",b.getBaseData());
53 info.append(buffer);
54 }
55
56 int main(int argc,char* argv[])
57 {
58 base b("test",10);
59 std::string s;
60 show(s,b);
61 std::cout<<s<<std::endl;
62 derived d("btest",5,"dtest");
63 std::string ss;
64 show(ss,d);
65 std::cout<<ss<<std::endl;
66 return 0;
67 }
运行结果为:
base:baseName is test, baseData is 10
base:baseName is btest, baseData is 5
下面改改代码,将函数参数变为derived
void show2(std::string& info,const derived& d)
{
info.append("Name is ");
info.append(d.getBaseName());
info.append(", baseData is ");
char buffer[10];
sprintf(buffer,"%d",d.getBaseData());
info.append(buffer);
}
调用show(ss,d);编译器报错
1 derived_class.cpp: In function `int main(int, char**)':
2 derived_class.cpp:84: error: invalid initialization of reference of type 'const derived&' from expression of type 'base'
3 derived_class.cpp:70: error: in passing argument 2 of `void show2(std::string&, const derived&)'
第二点对各种形式的继承作出验证,首先给出表格
继承方式\成员类型 | public | protected | private |
public | public | protected | 无法继承 |
protected | protected | protected | 无法继承 |
private | private | private | 无法继承 |
这里解释一下,这里仅仅表达基类的成员,被public,protected,private三种方式继承后,在原基类为public,protectedc,private的成员在继承类里类型为表格里内容
1 class base
2 {
3 public:
4 std::string testPublic()
5 {
6 return std::string("this is public base");
7 }
8 protected:
9 std::string testProtected()
10 {
11 return std::string("this is protected base");
12 }
13 private:
14 std::string testPrivate()
15 {
16 return std::string("this is private base");
17 }
18 };
19
20 class derivedPublic:public base
21 {
22 public:
23 std::string testPubPublic()
24 {
25 return testPublic()+= "in derived";
26 }
27
28 std::string testProPublic()
29 {
30 return testProtected()+= "in derived";
31 }
32
33 std::string testPriPublic()
34 {
35 return testPrivate()+= "in derived";
36 }
37 };
38
39 int main(int argc,char* argv[])
40 {
41 derivedPublic dpub;
42 std::cout << dpub.testPublic() << std::endl;
43 }
报下面错误,说明testPrivate()不是derived私有函数而是base的私有函数
derived11.cpp:16: error: `std::string base::testPrivate()' is private
derived11.cpp:36: error: within this context
这样验证private类型成员无法被继承(public,private,protected)注:private,protected略去不做证明
下面只要验证 testProtected 能被第三层继承类继承,但是无法被第三层类直接调用就说明是public继承后继承类型为protected,而基类为Public类型成员则即可被继承又可以直接调用。
1 #include <iostream>
2 #include <string>
3
4 class base
5 {
6 public:
7 std::string testPublic()
8 {
9 return std::string("this is public base");
10 }
11 protected:
12 std::string testProtected()
13 {
14 return std::string("this is protected base");
15 }
16 private:
17 std::string testPrivate()
18 {
19 return std::string("this is private base");
20 }
21 };
22
23 class derivedPublic:public base
24 {
25 public:
26 std::string testPubPublic()
27 {
28 return testPublic()+= "in derived";
29 }
30
31 std::string testProPublic()
32 {
33 return testProtected()+= "in derived";
34 }
35
36 // std::string testPriPublic()
37 // {
38 // return testPrivate()+= "in derived";
39 // }
40 };
41
42 class deepDerived:public derivedPublic
43 {
44 public:
45 std::string deepProtected()
46 {
47 return testProtected() +="in deep";
48 }
49
50 std::string deepPublic()
51 {
52 return testPublic() +="indeep";
53 }
54 };
55
56 int main(int argc,char* argv[])
57 {
58 derivedPublic dpub;
59 std::cout << dpub.testProtected() << std::endl;
60 deepDerived deepdpub;
61 std::cout<<deepdpub.testPublic() <<std::endl;
62 std::cout<<deepdpub.testProtected() <<std::endl;
63 std::cout<<deepdpub.deepProtected() <<std::endl;
64 std::cout<<deepdpub.deepPublic() <<std::endl;
65 }
这里服务器报错
derived12.cpp:13: error: `std::string base::testProtected()' is protected
derived12.cpp:62: error: within this context
这样就验证了一个是public,一个是protected,protected是不能直接调用的,但是被继承后是可以被public成员调用的。
下面的已经证明,详细步骤就略去如果对该部分验证感兴趣,可以看下面代码。
1 #include <iostream>
2 #include <string>
3 class base
4 {
5 public:
6 std::string testPublic()
7 {
8 return std::string("this is public base");
9 }
10 protected:
11 std::string testProtected()
12 {
13 return std::string("this is protected base");
14 }
15 private:
16 std::string testPrivate()
17 {
18 return std::string("this is private base");
19 }
20 };
21
22 class derivedPublic:public base
23 {
24 public:
25 std::string testPubPublic()
26 {
27 return testPublic()+= "in derived";
28 }
29
30 std::string testProPublic()
31 {
32 return testProtected()+= "in derived";
33 }
34
35 // std::string testPriPublic() //私有成员并没有被继承下来
36 // {
37 // return testPrivate()+= "in derived";
38 // }
39 };
40
41 class deepDerived:public derivedPublic
42 {
43 public:
44 std::string test()
45 {
46 return testPublic() +="in 3";
47 }
48 };
49
50 class derivedProtected:protected base
51 {
52 public:
53 std::string testPubProtected()
54 {
55 return testPublic()+= "in derived";
56 }
57
58 std::string testProProtected()
59 {
60 return testProtected()+= "in derived";
61 }
62 };
63
64 class deepDerived2:public derivedProtected
65 {
66 public:
67 std::string test()
68 {
69 return testPublic() +="in 3";
70 }
71 };
72
73 class derivedPrivate:private base
74 {
75 public:
76 std::string testPubPirvate()
77 {
78 return testPublic()+= "in derived";
79 }
80
81 std::string testProPrivate()
82 {
83 return testProtected()+= "in derived";
84 }
85
86 };
87
88 //class deepDerived3:public derivedPrivate
89 //{
90 // public:
91 // std::string test()
92 // {
93 // return testPublic() +="in 3";
94 // }
95 //};
96
97 int main(int argc,char* argv[])
98 {
99 derivedPublic dpub;
100 //derivedProtected dpro;
101 //derivedPrivate dpri;
102 std::cout<<dpub.testPublic()<<std::endl; //
103 //std::cout<<dpub.testProtected()<<std::endl; //用户被继承也是无法使用
104 //cout<<dpub.testPrivate()<<std::endl; //基类都是私有函数
105 std::cout<<dpub.testPubPublic()<<std::endl;
106 std::cout<<dpub.testProPublic()<<std::endl;
107 //std::cout<<dpub.testPriPrivate()<<std::endl; //没有被继承
108
109 deepDerived dd;
110 std::cout<<dd.test()<<std::endl;
111
112 derivedProtected dpro;
113 //std::cout<<dpro.testPublic()<<std::endl; //变成protected类型
114 std::cout<<dpro.testPubProtected()<<std::endl;
115 std::cout<<dpro.testProProtected()<<std::endl;
116
117 deepDerived2 dd2;
118 std::cout<<dd2.test()<<std::endl;
119
120 derivedPrivate dpri;
121 std::cout<<dpri.testPubPirvate()<<std::endl;
122 std::cout<<dpri.testProPrivate()<<std::endl;
123
124 // deepDerived3 dd3;
125 // std::cout<<dd3.test()<<std::endl;
126 }