C++:01.从C到C++:浅拷贝,优化规则,内存分配

new int[20]和new int[20]()
有()初始化为该类型的默认值       没有(为随机值)     开辟单个元素可以在()内随意初始化,但开辟数组是()内不能写入数字


类的成员方法在类体内定义和在类外定义:
1.类外定义的成员方法,在方法名字前面加类类型的作用域

2.类外定义的在调用时,有函数的正常开销(函数运行需要再栈上开辟内存);在类体内定义的函数,都被自动处理成inline内联函数(没有调用开销)


内存扩容(浅拷贝和深拷贝):

对于内置类型(指的就是int等),扩容时,可以直接使用memcpy&realloc等内存操作函数;

但是如果是对象类型,扩容时,一定不能够使用memcpy&realloc!!!

理由:这种操作是浅拷贝【如果对象的属性里有指针,则指针指向的是同一空间(访问的是同一内存),这种方法不可取,但如果没有指针,则无所谓】

在代码上如何解决浅拷贝问题?
                  1.提供自定义的拷贝构造函数和赋值重载函数operator=
                  2.拷贝构造函数和赋值重载函数声明成private的

一般来说最好自己写深拷贝,重新定义一个堆空间,将之前的内容复制到该空间。

CQueue(const CQueue &src)//队列
{
_pQue = new int[src._size];
memcpy(_pQue, src._pQue, sizeof(int)*src._size);
如果队列里放的是内置类型,可以用memcpy,如果是对象或带指针的,就只能用循环,一个一个赋值。
_front = src._front;
_rear = src._rear;
_size = src._size;
}

 优化规则:

用临时对象初始化同类型新对象的时候,临时对象就不产生了。所以用构造临时对象的方式,直接构造新对象就行了
           Test t3 = Test(10, 10);

在优化中注意的地方:

1:函数调用传参要传对象的引用!                                 eg:Test GetTestObject(Test &t)

2:函数返回值当中不要返回一个已经存在的对象,返回临时对象!!!  eg:return Test(value);

3:用初始化的方式接收一个返回值为对象的函数           eg: Test t2 = GetTestObject(t1);

补充解释:

函数返回值:小于4字节用eax寄存器。小于8字节,用eax,edx两个寄存器。当返回值大于8字节时,会产生临时量,当返回的是对象不管多大都会产生临时量,因为对象的构造一定会分配内存。

在调用函数之前会查看函数返回值如果返回值不为空,这个时候就已经在main函数栈帧上开辟了临时量的空间,就算函数没有参数,不需要参数传递,但其实还是传递了该临时量空间的地址。函数返回局部变量的时候就拷贝到这个临时量上了。

在了解了上述的基础上,我来详细解释下优化规则:

1、函数调用传参要传对象的引用! 如果不传引用,而是用值传递的方法,就会多实现一步对参数t的拷贝构造,并且出函数也会调用析构函数。

2、函数返回值中返回临时对象!  如果返回的是已存在的对象,这个对象肯定是函数里的局部变量,首先建立它的时候就会调用构造函数,出函数的时候先拷贝构造main函数栈帧上的临时对象,再对其本身进行析构。

1、用初始化的方式接收一个返回值为对象的函数!   如果不以初始化的方式接收,也就是说用的是已经存在的对象接收,当然会使用临时量调用赋值函数的重载。并且这个临时量也会析构。


内存分配:

我一直认为了解内存分配,可以更全面的理解代码。但之前一直是零零散散使用,并没有全面的认识,今天我打算对其进行简单整理:

 大体上是这样分配的,如果浏览该博文的哪位大佬发现有什么需要修改或补充的地方,还请及时告知我,不胜感激。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章