1. OOP思想
2. 面向对象语言的三大特征:封装,继承,多态
(1)封装和隐藏:
封装的实现:
访问限定符---public:公有的,哪里都可以访问
protected:保护的
private:私有的,除了类自己可以访问,其他的都不可以访问
类中的成员方法并不占用对象内存,成员方法均为指令,存放在 .text段,而成员变量是占用对象内存的。
This指针:指向调用该成员方法的对象,实际上this指针实际上存储该对象的内存的起始地址,而构造函数是对对象内存进行初始化,所以构造函数参数中是有this指针的。
Q:在cpp中,struct和class有什么区别
A:用struct和class定义类,当没有指定访问限定符时,
Struct默认是public,class默认是private;
Q:在类体中实现的成员方法和在类体外实现的成员方法的区别有哪些?
A:类体内实现的成员方法-----自动被编译成inline函数;
在类体外实现的成员方法---除非+inline关键字,否则和普通函数相同;
Q:通过函数名调用函数,和通过函数指针调用函数有什么区别?
A:函数指针调用函数:回调函数。
从调用函数开辟栈帧,栈帧回退来说,通过函数名调用函数,和通过函数指针调用函数没有区别;
*通过函数指针调用函数,不可能用到inline函数,inline函数是在编译阶段展开代码的,通过函数指针调用时,编译阶段并不执行代码,编译到函数指针时,并不能识别到inline函数。
所以,从这点来说,通过函数名调用函数的效率更高一点。
====================================================================================================================================
编译器自动产生的:(系统自动产生的函数两个特点:public和inline)
默认的构造函数 空
默认的析构函数 空
默认的拷贝构造 对象的内存互相初始化
默认的赋值运算符重载函数 对象内存的相互赋值
注:当有浅拷贝时,一定要自己重写拷贝构造函数和赋值运算符重载!
4..构造函数和析构函数:
(1) 构造函数可以加参数,即可以构成重载;
析构函数不可以加参数,即不可以构成函数的重载;
两者均没有返回值,但参数列表中具有this指针。
(2) 若自己没有提供任何的构造函数和析构函数,系统会产生默认的构造函数和默认的析构(系统产生的函数有两个特点public和inline);
若自己提供了任意一个构造函数,那么系统不会再产生默认的构造和析构;
(3) 定义对象时,编译系统调用构造函数,内存的开辟和构造函数是绑定在一起的(内存开辟后,构造函数对内存进行初始化)也可以将内存的开辟和构造函数调用分开-----定位new
(4) 编译系统什么时候调用构造函数(定义对象时)?什么时候调用析构函数(return语句)?
(5) 不可以手动调用构造函数,因为此时对象并没有存在(只是开辟了内存),构造函数的调用只能是编译系统在定义对象时调用;而析构函数可以自己调用,因为调用时对象是存在的,但当我们调用析构函数后,系统还是会再次调用析构函数。
(6) 构造函数并不是而对象分配内存,而是进行初始化;析构函数并不是释放对象的内存,而是在对象内存释放之前,释放对象占用的其他系统资源(如堆上内存)
(7) 构造和析构的顺序是相反的,先构造的对象后析构。
5.拷贝构造函数:
编译器编译一个类分三个步骤:
(1) 先扫描类名;
(2) 再扫描所有的成员名称(原型)
(3) 最后扫描所有的方法体和形参的默认值
区分初始化和赋值:
Eg: CGoods good1;
CGoods good2;
CGoods good3 = good2;//初始化,有一个新的对象生成
(等同于CGoods good3(goo2))
good1 = goo2;//赋值,没有新的对象生成,赋值运算符的重载
1. 当类内成员变量存在动态开辟内存,若使用默认的拷贝构造函数:
默认的拷贝构造函数将good1内存中的值放入good2;
出现问题:造成浅拷贝;当good2先析构,析构时释放了堆上的资源,从而使good1中的_pname指针成为野指针;
解决方法:当会出现浅拷贝现象时,要自己实现一个拷贝构造函数
CGoods(const CGoods &src)//这里只能传引用,若按值传递,会出现递归现象
Q:构造一个新对象,拷贝构造和构造,如何决定构造方式?
A:构造对象用户并不能自己选择哪个构造,构造的调用按照定义对象的方式调用
发生浅拷贝:对象占用了除了自己内存以外的其他系统资源,这样的对象若进行默认的拷贝构造,一定会发生浅拷贝;
6.赋值运算符重载函数
赋值,没有产生新的对象
出现的问题:1内存泄露;2.浅拷贝的发生
赋值运算符重载函数(不会产生新的对象,用于两个对象的赋值)
Void operator= (const CGoods &src)//此处可以按值传递,会调用拷贝构造函数产生临时对象,效率不高
注意点:
(1)防止自赋值;
(2)先释放当前对象占用的其他资源;
(3)再开辟资源;
(4)再进行赋值.