C++继承
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成员调用的。
下面的已经证明,详细步骤就略去如果对该部分验证感兴趣,可以看下面代码。
View Code
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 }