C++ Primer第七章总结
- this指针
- const成员函数(常量对象,以及常量对象的引用或指针都只能调用常量成员函数)
- 返回引用类型的函数返回值是一个左值,意味着这些函数返回的是对象本身而非对象的副本
- 定义在类内部的函数是隐式的inline函数
- 编译器分两步处理类:首先编译成员的声明,然后编译成员函数体
- IO类属于不能被拷贝的类型,在函数中只能通过引用来传递它们
- 构造函数
- class和struct的区别:默认访问权限不同,struct为public,class为private
- 友元
- 定义类型成员
- 可变数据成员mutable(任何成员函数,包括const函数在内都能改变它的值)
- 一个const成员函数如果以引用的形式返回*this,那么它的返回类型将是常量引用
- 类的作用域
- 隐式的类类型转换,explicit关键字的作用
- 类的静态成员(静态成员可以是函数也可以是数据,静态成员存在于所有对象之外)
书中的一个程序示例:
1 #include <iostream> 2 #include <string> 3 #include <sstream> 4 5 using namespace std; 6 7 class Screen{ 8 9 friend class Window_mgr; //如果一个类指定了友元类,则友元类的成员函数可以访问此类的所有成员(包括非公有成员在内) 10 11 public: 12 typedef std::string::size_type pos; 13 14 Screen() = default; 15 Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) {} 16 17 char get() const {return contents[cursor];} 18 inline char get(pos ht, pos wd) const; 19 20 Screen &move(pos r, pos c); 21 22 void some_member() const; 23 24 //set成员的返回值是调用set的对象的引用,返回引用的函数是左值的,意味着这些函数返回的是对象本身而非其副本 25 //调用myScreen.move(4, 0).set('#')时,这些操作将在同一个对象上执行 26 Screen &set(char); 27 Screen &set(pos, pos, char); 28 29 Screen &display(std::ostream &os){ 30 do_display(os); //调用do_display(os)时,this指针将隐式地从指向非常量的指针转换成指向常量的指针 31 return *this; //返回普通的(非常量)引用 32 } 33 34 const Screen &display(std::ostream &os) const{ 35 do_display(os); 36 return *this; //返回常量引用 37 } 38 private: 39 pos cursor = 0; 40 pos height = 0, width = 0; 41 std::string contents; 42 mutable size_t access_ctr; //可变数据成员,即使在一个const对象内也能被修改 (some_member()) 43 44 //负责打印Screen的实际工作,const成员函数,因为显示一个Screen不需要改变它的内容 45 void do_display(std::ostream &os) const {os << contents;} 46 }; 47 48 inline Screen &Screen::move(pos r, pos c){ //在函数的定义处指定inline 49 pos row = r * width; 50 cursor = row + c; 51 return *this; 52 } 53 54 char Screen::get(pos r, pos c) const{ //在类的内部声明成inline 55 pos row = r * width; 56 return contents[row + c]; 57 } 58 59 void Screen::some_member() const{ 60 ++access_ctr; //该成员是可变成员,任何成员函数,包括const函数在内都能改变它的值 61 } 62 63 inline Screen &Screen::set(char c){ 64 contents[cursor] = c; 65 return *this; 66 } 67 68 inline Screen &Screen::set(pos r, pos col, char ch){ 69 contents[r * width + col] = ch; 70 return *this; 71 } 72 73 74 75 class Window_mgr{ 76 public: 77 using ScreenIndex = std::vector<Screen>::size_type; 78 void clear(ScreenIndex); 79 ScreenIndex addScreen(const Screen&); 80 private: 81 std::vector<Screen> screens{Screen(24, 80, ' ')}; 82 }; 83 84 void Window_mgr::clear(int i){ 85 Screen &s = srceens[i]; //s是一个Screen的引用, 指向我们想要清空的那个屏幕 86 s.contents = string(s.height * s.width, ' '); 87 } 88 89 Window_mgr::ScreenIndex Window_mgr::addScreen(const Screen &s){ //要想使用ScreenIndex作为返回类型,必须明确指定哪个类型定义了它 90 screens.push_back(s); 91 return screens.size() - 1; 92 }