1.1 临时对象的引出 1.1.1思考程序输出
//下面程序的期望是 Test()中复用Test(int i)函数。但是实际结果不是自己想象的那样。因为构造函数的调用和普通函数是不同的。
class Test { private: int i ; public: Test() { Test(0); // 构造函数中调用构造函数 printf("Test()\n"); } Test(int i) { this->i =i; printf("Test(int i)\n"); } void print() { printf("i =%d\n",i); } ~Test() { printf("~Test() function i =%d\n",i); } }; int main() { Test t1; t1.print(); return 0; } 程序意图 (1)在Test() 中以0 作为参数调用Test(int i); (2)将成员变量mi的初始值设置为0运行结果1.1.2 案例二
class Test { private: int i ; public: Test(int i) { this->i =i; } void print() { printf("i =%d\n",i); } }; int main() { Test(10).print(); int(10) ; //通过类比,可以得出的内容 printf("int(10) = %d\n",int(10)); return 0; }结果: 1.1.3 构造函数分析 构造函数是一个特殊的函数
是否可以直接调用?是否可以在构造函数中调用构造函数?直接调用构造函数的行为是什么 ?直接调用构造函数的结果是什么
答案:
直接调用构造函数将产生一个临时对象临时对象的生命周期只有一条语句的时间临时对象的作用域只在一条语句中临时对象是C++中值得警惕的灰色地带1.1.4 解决方案
构建一个普通的初始化函数,然后构造函数调用这个初始化函数。 #include <stdio.h> #include <string.h> #include <stdlib.h> class Test { private: int i ; void init(int i) { this->i =i; } public: Test() { init(0); } Test(int i) { init(i); } void print() { printf("i =%d\n",i); } }; int main() { Test t1; t1.print(); return 0; }1.2 1.2.1
现代C++编译器在不影响最终执行结果的情况下,会尽力减少临时对象的产生。之前课程中介绍的copy构造函数第四种调用时机和临时对象之间的关系。 注意下面两种情况下,哪种会调用copy 构造函数。 Test func() { return Test(10); //不会调用Copy构造 } Test func() { Test t(10); return t; // 会调用copy构造函数。 }1.3const 对象
1.3.1 问题提出 const 可以修饰普通类型的数据比如const int a =10; 类也是一种类型,那么可以用const修饰类类型的变量吗?(类类型的变量也就是类的对象) const修饰的变量有什么特性呢?
1.3.2 const 对象
const 关键字能够修饰对象const 修饰的对象是只读对象(不能出现在赋值符合的左边)只读对象的成员变量不允许被改变只读对象是编译阶段的概念,运行时无效1.3.3 C++中的const 成员函数
const对象只能调用const 的成员函数
const成员函数只能调用const成员函数
const成员函数不能直接改写成员变量的值
const成员函数的语法规则: (1) int ClassName::functionName(int a) const (2) const 在这了修饰的是this指针。等价于 int ClassName::functionName(const ClassName * const this,int a)
注意: this 指针本来就是常量指针
注意:类中的函数声明和实际函数定义中都必须带const 关键字。
1.4 经典问题 1.4.1 成员函数和成员变量都是隶属于具体对象的吗?
从面向对象的角度 对象由属性(成员变量)和方法(成员函数)构成 从程序运行的角度 对象由数据和函数构成 数据可以位于栈,堆和全局数据区函数只能位于代码段1.4.2 结论
每一个对象拥有自己独立的属性(成员变量)所有的对象共享类的方法方法能够直接访问对象的属性方法中的隐藏参数 this 用于指代当前对象成员函数只有一套,成员函数可以直接访问对应类的任意对象的成员变量1.4.3
class Test { private: int mi; public: Test(int i) { mi =i; } Test(const Test&j) { mi =j.mi; //why sucess 成员函数只有一套,成员函数可以直接访问对应类的任意对象的成员变量 // mi = j.getMi(); //why error const 对象只能调用const成员函数 printf("Test(const Test&j)\n"); } int getMi() // need int getMi() const { return mi ; } void print() { printf("Test %p\n",this); } }; int main() { Test t1(1); printf("Test t1 =%p\n",&t1); t1.print(); Test t2(2); printf("Test t2 =%p\n",&t2); t2.print(); Test t3 = t1; return 0; }参考一 :狄泰软件学院C++进阶剖析
