类的基本思想:数据抽象和封装。
数据抽象依赖接口和实现分离的编程技术。
类的设计者来思考类的实现过程。使用类的程序员只需要抽象的思考类型做了什么。
设计一个类,就是一个创造的过程。过程中需要考虑如何使得类易于使用。一个优秀的类,既要有直观易于使用的接口,也必须具备高效的实现过程。
1. 关于this
this是类额外的隐式参数。
当我们调用类的成员函数,默认有一个该类对象的this参数传入成员函数的参数中。
当我们在类的内部,可以直接调用函数对象的成员,因为this所指的就是这个对象。
this是一个常量指针。我们不允许改变this中保持的地址。
2. 关于const成员函数
该const关键字,出现在紧随函数的参数列表之后。
他主要作用与this隐式参数,是的this指针变成一个指向常量的常量指针。
同样,使用const修饰的成员函数,被成为常量成员函数。
这样的目的是:使得常量成员函数不能改变调用他的对象的内容。
同样,常量对象,或者对常量对象的引用和指针,都只能调用常量成员函数。
3. 返回 this的成员函数
举个primer中的例子:
class Screen {
public:
using pos = std::string::size_type;
Screen() = default; // 1
Screen(pos ht, pos wd) : height(ht), width(wd), contents(ht * wd, ' ') {} // 2
Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c)
{
} // 3
char get() const { return contents[cursor]; }
char get(pos r, pos c) const { return contents[r * width + c]; }
inline Screen& move(pos r, pos c);
inline Screen& set(char c);
inline Screen& set(pos r, pos c, char ch);
const Screen& display(std::ostream& os) const
{
do_display(os);
return *this;
}
Screen& display(std::ostream& os)
{
do_display(os);
return *this;
}
private:
void do_display(std::ostream& os) const { os << contents; }
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
};
我们重点来看两个display函数。
const Screen& display(std::ostream& os) const
{
do_display(os);
return *this;
}
上述的display函数是一个const成员函数,按照第二部分的讲述,const成员函数,意味着,this指针是一个指向常量的常量指针。所以如果我们想要返回this指针的话,必须返回const Screen&
类型
但是,const成员函数只能被const对象调用,如果我们有非const对象想要实现display操作,就需要对display函数进行重载。
Screen& display(std::ostream& os)
{
do_display(os);
return *this;
}
最后,思考下函数do_display
void do_display(std::ostream& os) const { os << contents; }
该函数是一个私有的const成员函数。
当被const版本的display调用的时候,传入的*this是一个指向常量的指针。
当被非const版本的display调用时,传入的是正常的this指针。