学习C++的道路 博主会持续更新的
2018.9.3 今天开始正式上课了 也是好好开始学习C++的日子了
今天买了两本书 C++项目开发 与 C接口----等我的书回来一定要好好的学习一波
博主用的编译软件是VS2017 ----- 地址 : https://visualstudio.microsoft.com/zh-hans/vs/whatsnew/
今天:学习了利用继承改写组合关系 我把今天写的笔记总结了下来 如下(有写的不对的地方,大家不要见怪 提出来我们共同解决):
1 /* 2 8:继承使用的两种情况 3 (1)、类之间有自然的继承关系,一个类另一个类的特例。 4 fx:一个学生是一个人 5 (2)、实现代码复用,一个类需要使用另一个类中的成员时 6 9:继承的好处 7 (1)、代码复用 code reuse 8 (2)、使代码容易修改 9 10:两个类之间的交互关系 10 (1)、组合类 ------》 一个类中有另一个类的对象 has-a的关系 11 ====== 组合改继承 那么 我们可以一步一步去拆分进而去得到 12 (2)、继承 ------》 一个雷是另一个类的特例 is-a的关系 13 14 学到了学到了 输出运算符重载 15 ostream & operator << (ostream & os, Point & apoint){ 16 os << "Point:X:Y: "<<apoint.x<<","<<apoint.y<<" "; 17 return os; 18 //其中 Point是具体的某一个类 这个类名是可以进行更改的 19 } 20 21 */ 22 #include <iostream> 23 using namespace std; 24 class Point { 25 26 }; 27 28 class Circle { 29 private: 30 Point center; 31 float radius; 32 }; 33 34 class Cylinder { 35 private: 36 Circle c; 37 float height; 38 }; 39 40 //上边是用组合来写的 41 //接下来给出用继承来写 42 class Point1{ 43 private: 44 float x, y; 45 }; 46 47 class Circle1:Point1 { 48 private: 49 float radious; 50 }; 51 52 class Cylinder : Circle1 { 53 private: 54 float height; //自己扩展 + 父类的成员 + 爷爷的成员 55 }; 56 57 //接下来书写组合改继承的具体代码 注意:与上边要分开 否则一起运行时会报错的 58 59 #include <iostream> 60 #include <cmath> 61 using namespace std; 62 63 class Point { 64 friend ostream & operator << (ostream & , Point & ); 65 protected: 66 double x, y; 67 public: 68 Point():x(0),y(0){} 69 Point(double _x, double _y) { 70 x = _x; 71 y = _y; 72 } 73 }; 74 75 ostream & operator << (ostream & os, Point & apoint) { 76 os << "Point:X:Y " << apoint.x << "." << apoint.y << " "; 77 return os; 78 } 79 80 //圆继承点 81 class Circle : public Point{ 82 friend ostream & operator << (ostream &, Circle &); 83 protected: 84 double radius; 85 public: 86 Circle():Point(),radius(0){} 87 Circle(double r,double xval,double yval):Point(xval,yval),radius(r){} 88 89 double area() { 90 return (3.14159 * radius * radius); 91 } 92 }; 93 94 ostream & operator << (ostream & os, Circle & aCircle) { 95 os << "Cicle:radius:" << aCircle.radius; 96 os << aCircle.x << " "; 97 os << aCircle.y << " "; 98 return os; 99 } 100 101 class Cylinder :public Circle { 102 friend ostream & operator << (ostream &, Cylinder &); 103 protected: 104 double height; 105 public: 106 Cylinder() :Circle() { height = 0.0; } 107 Cylinder(double hv, double rv, double xv, double yv) :Circle(rv, xv, yv) { 108 height = hv; 109 } 110 111 double area() { 112 return (2 * Circle::area() + 2 * 3.14159 * radius * height); 113 } 114 }; 115 116 ostream & operator << (ostream & os, Cylinder & acylinder) { 117 os << "cylinder dimensions"; 118 os << "x:" << acylinder.x; 119 os << " y:" << acylinder.y; 120 os << " radius: " << acylinder.radius; 121 os << " height: " << acylinder.height << endl; 122 return os; 123 } 124 125 int main(int argc, const char * argv[]) { 126 Point p(2, 3); 127 Circle c(7, 6, 5); 128 Cylinder cyl(10, 11, 12, 13); //半径不同 调用的函数变量的值不同 129 130 cout << p; 131 cout << c; 132 cout << "area circle:" << c.area() << endl; 133 134 cout << cyl; 135 cout << "area cylinder:" << cyl.area() << endl; 136 137 cout << "area cylinder base is " << cyl.Circle::area() << endl; 138 139 return 0; 140 }
很开心今天书回来了 好好学习
//今天学习到很过干货
1、子类的析构函数会自动会调用父类的析构函数
2、析构函数是存储保存在栈中的 所以在输出析构函数的时候是有一定的顺序的
3、虚函数----》这是个重点
(1)、在使用虚函数之后可以不去使用向下转型
(2)、期望父类指针。不管指向父类还是子类,在调用override函数是,反映真实情况
(3)、指针或者引用所指向的对象的类型来确定
4、多态-----个人理解(多种形态)
fx:
//Base *p = &d1; //其实与多态类似 主类的指针在不断的变化
//p = &d2; //虚函数的时候只需要改指向就ok
//p = &b; //指哪一个调用哪一个
今天的代码:
1 //虚函数与多态 2 /* 3 虚函数的使用(根据父类的引用的指向来选择进行哪一个实现) 4 虚函数的作用: 5 (1)、无需向下转型,就可以正确的用父类的指针或引用 6 (2)、期望父类指针。不管指向父类还是子类,在调用override函数是,反映真实情况 7 (3)、指针或者引用所指向的对象的类型来确定 8 */ 9 #include <iostream> 10 using namespace std; 11 12 class Base { 13 public: 14 virtual void func() { 15 cout << "Base function" << endl; 16 } 17 }; 18 19 class Derived1 :public Base { 20 public: 21 void func() { 22 cout << "Derived1 function" << endl; 23 } 24 }; 25 26 class Derived2 :public Base { 27 public: 28 void func() { 29 cout << "Derived2 function" << endl; 30 } 31 }; 32 33 void foo(Base & b) { 34 b.func(); 35 } 36 37 int main() { 38 //虚函数(一) 39 /* 40 Base b; 41 Derived1 d; 42 Base *p = &d; //父类指针指向子类对象 43 Base & br = d; //父类引用指向子类对象 44 b.func(); //父类版本 45 d.func(); //子类版本 46 p->func(); //父类 47 br.func(); 48 foo(b); 49 */ 50 51 52 //虚函数(二) 53 Base b; 54 Derived1 d1; 55 Derived2 d2; 56 57 //Base *p = &d1; //其实与多态类似 主类的指针在不断的变化 58 //p = &d2; //虚函数的时候只需要改指向就ok 59 //p = &b; //指哪一个调用哪一个 60 //p->func(); 61 62 63 Base *p[3] = { &b,&d1,&d2 }; //父类指针数组 --------> 厉害 厉害 学到了 学到了 64 for (int i = 0; i < 3; ++i) 65 { 66 p[i]->func(); 67 } 68 return 0; 69 } 70 71 //加强虚函数的使用 72 #include <iostream> 73 using namespace std; 74 75 class Thing { 76 public: 77 virtual void what_Am_I() { 78 cout << "I am a Thing. "; 79 } 80 ~Thing() { 81 cout << "Thing destructor" << endl; 82 } 83 }; 84 85 class Animal : public Thing { 86 public: 87 virtual void what_Am_I() { 88 cout << "I am a Animal. "; 89 } 90 91 //子类析构函数会自动调用父类的析构函数 92 //注意析构函数的存储是保存在栈中的 所以这边输出的时候是有一定的顺序的 93 ~Animal() { 94 cout << "Animal destructor" << endl; 95 } 96 }; 97 98 int main() { 99 Thing t; 100 Animal x; 101 Thing* array[2]; //声明一个父类指针数组 102 array[0] = &t; 103 array[1] = &x; 104 for (int i = 0; i < 2; i++) { 105 array[i]->what_Am_I(); 106 } 107 return 0; 108 }