参考自《C++ Primer Plus 6th Edition》和 《C++ Primer 5th Edition》
(本博文中知识点较为零散和基础,主要用于本人的学习回顾)
访问所创建对象的公有成员
1. 自动存储类对象: "句点方法"
2. 动态存储类对象(使用new): 我们创建了一个匿名的对象,并把这个对象的地址传给了一个指针。我们可以使用指针的指向符"->"来访问公有成员,也可以使用"*"对指针进行反引用,然后用"句点方法"来访问公有的成员变量。
e.g.
Stock * A = new Stock; // 动态创建一个Stock对象,把对象的地址赋给指针A A->show() // accepted (*A).show() // accepted
3. 静态存储类对象: "句点方法"
4. 临时对象: "句点方法"
创建对象的一种语法可能会导致编译器的两种理解
e.g. Stock stock = Stock();
在这个语句中,按照C++标准,编译器有两种可能的方式来执行这个语法:
1. 将语句理解为: Stock stock;
2. 先创建一个Stock类的临时对象,再将这个临时对象复制到stock
const成员函数
若你创建了一个用const 修饰的类对象,则它被禁止调用一个没有用const修饰的成员函数
因为,你不能向编译器保证,你的这个成员函数的函数体不会修改调用它的对象
打个比方,比如你定义了一个用const 修饰的变量,还有一个函数,这个函数的其中一个参数是同类型的一个引用
如果你要把这个const 变量当作这个参数传给函数,那么这个形参列表的这个引用要用const 修饰,这样才能保证不修改这个常量
e.g.
void test(const int & r) { std::cout << "hello world !\n"; } int main(int argc , char *argv[] ) { const int a = 5; test(a); return 0; }
但是问题来了,这个例子不能类比用来解决问题啊! 因为对象调用成员函数的时侯,不能显式地把自己当成参数传到成员函数的形参列表中!其实对象直接调用成员函数或对象指针间接调用成员函数的时侯,会把真正对象的地址传给成员函数中隐藏的参数this指针。而且成员函数中涉及成员变量的访问都要通过this指针来访问。问题的症结就在于: 怎么保证函数的执行过程中,this所指对象中的成员变量不会被修改?
C++引入了一种语法来解决这个问题:将const限定符放在函数的括号后面。没错!这个const正是对this进行限定的!为啥要放在小括号后面,大括号前面呢 ?因为this在形参列表中对我们是隐藏的,当然就不可能放在形参列表中啦。 自此,我们就不能使用this来修改对象的值了。
由以上,我们可以总结出一个好的编程习惯: 按《C++ primer plus 6th Edition》上的原话--“就像尽可能将const引用和指针用作函数行参一样,只要类方法不修改调用对象,就应该将其声明为const”,不管所创建的对象是否使用const修饰,这是一个很好的编程习惯! 类似地,可以推广到普通函数的使用中。
就像这样:
void show() const;
这是声明的时侯。实现的时侯呢,把const放在形参列表后面,函数体的花括号前面即可。
void Stock::show() const { /* implementation*/ }