第6章 当c++爱上面向对象
6.1 从结构化设计到面向对象程序设计
6.1.1 "自顶向下,逐步求精"的结构化程序设计
6.1.2 面向对象程序设计
6.1.3 面向对象的三座基石:封装、继承与多态
6.2 类:当c++爱上面向对象
6.2.1 类的声明和定义
6.2.2 使用类创建对象
6.2.3 构造函数和析构函数
6.2.4 拷贝构造函数
6.2.5 操作符重载
6.2.6 类成员的访问控制
6.2.7 在友元中访问类的隐藏信息
6.3 类如何面向对象
6.3.1 用类机制实现封装
6.3.2 用基类和派生类实现继承
6.3.3 用虚函数实现多态
6.4 实战面向对象:工资管理系统
6.4.1 从问题描述中发现对象
6.4.2 分析对象的属性和行为
6.4.3 实现类的属性和行为
6.5 高手是这样炼成的
6.5.1 c++类对象的内存模型
6.5.2 指向自身的this指针
这本书错误实在太多了,后面浏览,代码不整理了!
//p145 #include <iostream> using namespace std; struct rect { int w,h; //成员变量 int getarea() //成员函数 { return w*h; } }; int main() { rect re; //定义一个rect变量 re.w=3; //因为是struct,可以直接访问成员变量 re.h=4; //也可以直接访问成员函数 cout<<"The area is: "<<re.getarea()<<endl; return 0; } //p144-146 #include <iostream> #include <string> using namespace std; class Teacher { public: void PrepareLesson(); //成员函数 protected: string name; private: }; void Teacher::PrepareLesson() //在外部定义成员函数 { cout<<"Preparing..."<<endl; } int main() { Teacher MrChen; // 用类创建一个对象。即创建一个Teacher变量 MrChen.PrepareLesson(); //因为public,所以可以访问 return 0; } //p146-147 #include <iostream> #include <string> using namespace std; class Teacher { public: void PrepareLesson(); //成员函数 protected: string name; //成员变量 private: }; void Teacher::PrepareLesson() //在外部定义成员函数 { cout<<"Preparing..."<<endl; } int main() { Teacher MrChen; // 用类创建一个对象。即创建一个Teacher变量 MrChen.PrepareLesson(); //因为public,所以可以访问 Teacher *pMrChen=NULL; //与其他变量一样,可以定义指针 pMrChen=&MrChen; pMrChen->PrepareLesson(); Teacher *p=new Teacher(); // 用new创建新对象 p->PrepareLesson(); delete p; // 用new创建的,要用delete释放内存 return 0; } //p149 #include <iostream> #include <string> using namespace std; class Teacher { public: Teacher(string strName) //构造函数 { name=strName; } void PrepareLesson(); //成员函数 protected: string name; //成员变量 private: }; void Teacher::PrepareLesson() //在外部定义成员函数 { cout<<"Preparing..."<<endl; } int main() { Teacher MrChen("ChenXX"); // 有自定义构造函数后,可以赋初值了 //cout<< MrChen.name << endl; //但是,name受保护,不能访问 MrChen.PrepareLesson(); //因为public,所以可以访问 return 0; } //p150 初始化列表 #include <iostream> #include <string> using namespace std; class Teacher { public: Teacher(string strName,int nage) :name(strName),age(nage){} //初始化列表,来代替构造函数 void PrepareLesson(); //成员函数 protected: string name; //成员变量 private: int age; //加一个成员变量 }; void Teacher::PrepareLesson() //在外部定义成员函数 { cout<<"Preparing..."<<endl; } int main() { Teacher MrChen("ChenXX",88); // 加了一个成员,同样是受保护的 //cout<< MrChen.name << endl; //但是,name受保护,不能访问 MrChen.PrepareLesson(); //因为public,所以可以访问 return 0; } //p151 析构函数 #include <iostream> #include <string> using namespace std; class Teacher { public: Teacher(string strName,int nage) :name(strName),age(nage){} //初始化列表,来代替构造函数 void PrepareLesson(); //成员函数 ~Teacher() { cout<<"is it doing?"<<endl; //真有 }; protected: string name; //成员变量 private: int age; //加一个成员变量 }; void Teacher::PrepareLesson() //在外部定义成员函数 { cout<<"Preparing..."<<endl; } int main() { Teacher MrChen("ChenXX",88); // 加了一个成员,同样是受保护的 //cout<< MrChen.name << endl; //但是,name受保护,不能访问 MrChen.PrepareLesson(); //因为public,所以可以访问 cout<<"now..."<<endl; //观察析构函数啥时运行——程序结束之前 return 0; } //p152 拷贝构造函数 #include <iostream> #include <string> using namespace std; class Teacher { public: Teacher(string strName,int nage) :name(strName),age(nage){} void PrepareLesson(); protected: string name; private: int age; }; void Teacher::PrepareLesson() //在外部定义成员函数 { cout<<"Preparing..."<<endl; } int main() { Teacher MrChen("ChenXX",88); //如果不赋初值,无法建立副本 Teacher MissLi(MrChen); //建立一个副本 //Teacher MissLi; //与一般变量不同 //MissLi=MrChen; //这样是不可以嘀 MrChen.PrepareLesson(); MissLi.PrepareLesson(); return 0; } //p152 试下 assert 是干啥嘀? #include <iostream> #include <string> #include <assert.h> using namespace std; int main() { cout << "begin..." << endl; assert( 1==1 ); cout << "......" << endl; assert( 1==0 ); // 返回假时,中断执行了。。 cout << "end..." << endl; return 0; } //p152 看下,不自定义拷贝构造函数,会咋样? #include <iostream> #include <string> #include <assert.h> using namespace std; struct Keyboard { string m_strModel; //键盘型号 }; class Computer { public: Computer( Keyboard *nullptr, string str ) :m_pKeyboard(nullptr),m_strModel(str){} Keyboard* GetKeyboard() const //函数返回指针类型 { return m_pKeyboard; } string GetStr() const { return m_strModel; } private: Keyboard *m_pKeyboard; //指针类型的成员 string m_strModel; }; int main() { Keyboard keyboard; Keyboard* p; p=&keyboard; p->m_strModel="test"; Computer oldcom(p,p->m_strModel); cout<<oldcom.GetKeyboard()<<endl; //输出指针 cout<<oldcom.GetStr()<<endl; //输出型号 // Computer newcom(oldcom); cout<<newcom.GetKeyboard()<<endl; //输出指针 cout<<newcom.GetStr()<<endl; //输出型号 return 0; //观察输出知道,确实完美拷贝,一模一样 } /* //p152 接下来,问题来了。 这个代码是编译不通的,因为nullptr */ #include <iostream> #include <string> #include <assert.h> using namespace std; struct Keyboard { string m_strModel; //键盘型号 }; class Computer { public: //Computer(Keyboard *nullptr):m_pKeyboard(nullptr){} Computer():m_pKeyboard(nullptr){} Computer(const Computer& com):m_strModel(com.m_strModel) { Keyboard *pOldKeyboard=com.GetKeyboard(); if( nullptr!=pOldKeyboard) m_pKeyboard = new Keyboard(*(pOldKeyboard)); else m_pKeyboard=nullptr; } // void SetKeyboard(Keyboard *pKeyboard) { m_pKeyboard=pKeyboard; } Keyboard* GetKeyboard() const //函数返回指针类型 { return m_pKeyboard; } // private: Keyboard *m_pKeyboard; //指针类型的成员 string m_strModel; }; int main() { Computer oldcom; Keyboard keyboard; keyboard.m_strModel="Microsoft-101"; oldcom.SetKeyboard(&keyboard); Computer newcom(oldcom); assert( newcom.GetKeyboard() != oldcom.GetKeyboard() ); assert( newcom.GetKeyboard()->m_strModel != oldcom.GetKeyboard()->m_strModel ); return 0; }