类的其他特性
来源:互联网 发布:人工智能的产品有哪些 编辑:程序博客网 时间:2024/06/07 08:37
#include <iostream>#include <string>using namespace std;class Screen{public: typedef std::string::size_type pos; // using pos=std::string::size_type; 同上等价 Screen() = default; //因为Screen有另一个构造函数, //所以本函数是必须的,默认方式 Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd, c){} //contents初始化的意思是,有ht乘wd个字符c初始化一个string类型 char get() const //读取光标处的字符 { return contents[cursor]; //隐式内联 } inline char get(pos ht, pos wd) const; //显式内联 Screen &move(pos r, pos c); //能在之后被设为内联private: pos cursor = 0; pos height = 0, width = 0; std::string contents;};//虽然我们没必要在类的里面和外面都用inline来声明,但是这样//是合法的,不过最好只在类的外部说明inline,这样更容易理解inline //可以在函数的定义处指定Screen &Screen::move(pos r, pos c){ pos row = r*width; //计算行的位置 cursor = row + c; //在行内将光标移到到指定的列 return *this; //以左值的形式返回对象}char Screen::get(pos r, pos c) const //在类的内部声明成inline{ pos row = r*width; //计算行的位置 return contents[row + c]; //返回给定列的字符}int main(){ Screen p(10, 10,'a'); char k = p.get(5,7); cout << k << endl; return 0;}
内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理
内联说明(inline specification)对于编译器来说只是一个建议,编译器可以选择忽略这个建议
char k = p.get(5,7);00CD6435 push 7 00CD6437 push 5 00CD6439 lea ecx,[ebp-3Ch] //采用的调用的方式来调用内联函数,所以说明内联函数没有嵌入到调用处00CD643C call 00CD14D8 00CD6441 mov byte ptr [ebp-45h],al
可变数据成员
使用关键字mutable,这样一个const成员函数也可以改变一个可变成员的值了
类内初始值就是把类内部的数据进行默认初始化,要么放在花括号里面,要么放在=号右边,不能使用圆括号
class Screen{public: typedef std::string::size_type pos;// using pos=std::string::size_type; 同上等价 Screen()=default; //因为Screen有另一个构造函数, //所以本函数是必须的,默认方式 Screen(pos ht, pos wd, char c):height(ht), width(wd), contents(ht*wd,c){} //contents初始化的意思是,有ht乘wd个字符c初始化一个string类型 char get() const //读取光标处的字符 { return contents[cursor]; //隐式内联 } inline char get(pos ht, pos wd) const; //显式内联 Screen &move(pos r, pos c); //能在之后被设为内联 void some_member() const;private: pos cursor=0; pos height=0, width=0; std::string contents; mutable size_t access_ctr; //即使在一个const对象内也能被修改};//虽然我们没必要在类的里面和外面都用inline来声明,但是这样//是合法的,不过最好只在类的外部说明inline,这样更容易理解inline //可以在函数的定义处指定Screen &Screen::move(pos r, pos c){ pos row=r*width; //计算行的位置 cursor=row+c; //在行内将光标移到到指定的列 return *this; //以左值的形式返回对象}char Screen::get(pos r, pos c) const //在类的内部声明成inline{ pos row=r*width; //计算行的位置 return contents[row+c]; //返回给定列的字符}void Screen::some_member() const{ ++access_ctr; //保管一个计数值,用于记录成员函数被调用的次数}class Window_mgr{private: //这个Window_mgr追踪的Screen //默认情况下,一个Window_mgr包含一个标准尺寸的空白Screen std::vector<Screen> screens{Screen(24, 80, ' ')};};
返回*this的成员函数
返回*this的成员函数,则调用的直接就是类的对象本身,而不是他的副本。
#include <iostream>#include <string>using namespace std;class Screen{public: typedef std::string::size_type index; Screen(index ht = 0, index wd = 0) :contents(ht*wd, 'A'), cursor(0), height(ht), width(wd) {} char get() const{ return contents[cursor]; } char get(index r, index c)const { index row = r*width; return contents[row + c]; } Screen& move(index r, index c); Screen& set(index, index, char); Screen& set(char);private: std::string contents; index cursor; index height, width;};Screen& Screen::move(index r, index c){ index row = r*width; cursor = row + c; return *this;}Screen& Screen::set(index r, index c, char ch){ index row = r*width; contents[row + c] = ch; return *this;}Screen& Screen::set(char c){ contents[cursor] = c; return *this;}int main(){ Screen myScreen(5, 5); myScreen.move(4, 0).set('#'); cout << myScreen.get() << endl;}
从const成员函数返回*this
在普通的非const成员函数中,this的类型是一个指向类类型的const指针,可以改变this所指向的值,但不能改变this所保存的地址。在const成员函数中,this的类型是一个指向const类类型的const指针,既不能改变this所指向的对象,也不能改变this所保存的地址
不能从const所员函数返回指向类对象的普通引用。const成员函数只能返回*this作为一个const 引用。
基于const的重载:
#include <iostream>#include <string>using namespace std;class Screen{public: typedef std::string::size_type index; Screen(index ht = 0, index wd = 0) :contents(ht*wd, 'A'), cursor(0), height(ht), width(wd) {} char get() const{ return contents[cursor]; } char get(index r, index c)const { index row = r*width; return contents[row + c]; } Screen& move(index r, index c); Screen& set(index, index, char); Screen& set(char); const Screen& display(std::ostream &os)const { do_display(os); return *this; } Screen& display(std::ostream &os) { do_display(os); return *this; }private: std::string contents; index cursor; index height, width; void do_display(std::ostream &os)const { os << contents; }};Screen& Screen::move(index r, index c){ index row = r*width; cursor = row + c; return *this;}Screen& Screen::set(index r, index c, char ch){ index row = r*width; contents[row + c] = ch; return *this;}Screen& Screen::set(char c){ contents[cursor] = c; return *this;}int main(){ Screen myScreen(3, 3); myScreen.display(cout).set('#').display(cout); cout << endl; const Screen blank(3, 3); myScreen.set('#').display(cout);//调用非常量版本 cout << endl; blank.display(cout);//调用常量版本 return 0;}
书本P144说:允许指向非常量类型指针转换成指向相应的常量类型指针,对于引用也是这样。也就是说,如果T是一种类型,我们就能将指向T的指针或引用分别装换成指向const T的指针或类型。
一个成员调用另一个成员时,this指针在其中隐式地传递。因此,当display调用do_display时,它的this指针将隐式地从指向非常量的指针转换成指向常量的指针。当do_display完成后,display函数各自解引用this所得的对象。在非常量版本中,this指向一个非常量对象,因此display返回一个普通的(非常量)引用;而const成员则返回一个常量引用。
- 类的其他特性
- android wear的其他特性
- 【足迹C++primer】17、类的其他特性
- 【足迹C++ primer】17、类的其他特性(2)
- java8新特性_其他类库的变化
- 其他语言无法比拟的Python特性
- 《C++ Primer》读书笔记第七章-2-类的其他特性 And 类的作用域
- IBatis 其他重要特性
- 5. 其他 C++ 特性
- ASIHTTPRequest-其他特性
- ASIHTTPRequest-其他特性
- ASIHTTPRequest-其他特性
- C++ - 其他特性
- ASIHTTPRequest-其他特性
- ASIHTTPRequest-其他特性
- java 其他特性
- java8-04-其他特性
- jmeter其他特性---工作台
- 理解本真的REST架构风格
- Ubuntu下安装CUDA 7.5教程——真正的简便
- android开发笔记之Gson解析
- 记录下自己的脑X错误
- android之context(上下文)、五大布局
- 类的其他特性
- iOS教程:如何仿一款“账本”上架app(一)
- 学习篇---幸运转盘
- Spark Streaming源码解读之JobScheduler内幕实现和深度思考
- Hust oj 2084(大数)
- Android Drawable - Inset Drawable使用详解(附图)
- SQL Server error '80040e14'的处理
- 必须跟你说点事《TCP 三次握手》
- MySQL 5.6内存占用过高解决方案【总结】