带指针成员的类
1. 拷贝构造函数(copy ctor)
拷贝构造函数就是构造函数做接受的对象是自己这个类的对象。
编译器自带拷贝构造是为了把一个类的每一个字节的内容完全拷贝到另一个新的对象里面。
但是如果对象里面有指针也只是把指针的值拷贝到另一个对象里面,但是两个对象里面指针所指
的值是同一个,并没有两个一模一样的值。所以如果类带有指针就必须自己写拷贝构造函数。
class_name(class_name &);
需要先申请动态申请一块足够大的内存空间。然后把另一个对象的指针所指的值拷贝到刚刚
申请的内存空间。
2. 拷贝赋值函数 (copy op=)
和拷贝构造一样,如果没有这个函数编译器只会把指针变量的值复制到另一个对象里面去,
但是这两个指针变量所指同一块内存空间,对一个对象操作会影响另一个对象,达不到预期值。
所以带指针的类需要自定义拷贝赋值函数。
1. 检测自我赋值,防止在delete时对数据造成破坏:
2. delete该对象原来申请的内存空间;
3. 重新申请一块新的内存空间;
4. 把另一个对象的值拷贝到该对象。
拷贝赋值,需要进行检测自我赋值,防止整个对象被delete销毁了。
3. 动态内存分配
在不确定一个对象有多大的时候可以动态分配一块内存空间,动态分配的内存空间不会自动
消失,所以需要自己进行空间释放,防止内存泄漏。
new 类型名[多少个这个类型的对象]/类的构造函数;//返回值为一个指针,先申请空间,在调
//用构造函数。
delete[] 指针;//释放刚刚new的内存空间,先调用析构函数在释放内存。如果没有[]的话,
//就有可能导致对象中指针所指的内存泄漏,因为只会调用一次析构函数。
4. 析构函数(dtor)
由于动态内存空间就算离开了对象所处的作用域对象也不会自动消失,所以在析构函数里面,
就需要使用delete释放空间。
~class_name();
5. 堆(heap)栈(stack)
内存从高地址到低地址,分别是stack,heap,static object,stack地址往下增长,heap地址往上增长。
static对象在作用域结束之后仍然存在,直到程序结束。
global对象比main还要更早的存在,main函数结束之后才消失。
stack对象在创建时出现,作用域结束之后调用析构函数。
heap对象new的时候开始存在,delete时才消失。如果没有delete会在作用域结束时指针消
失但是值仍然存在。创建heap对象分为三个步骤:
1.动态申请一块内存空间;2.在这块内存上创建一个对象;3.返回内存指针。
6. static
数据前加上static,使所有的同类对象都只有同一个静态数据,所又对象公用。静态数据必
须在类的定义外面进行定义。
成员函数前加上static,没有this指针,只能用于处理静态数据。可以通过对象进行调用也
可以在没有对象的时候通过class name来调用。
7. 模板( template)
类模板可以不限定类里面成员的类型,按照需要自己设定。使用时需明确指出typename。
template<typename T>
函数模板可以不限定函数里面参数的类,按照需要自己设定。不需要明确指出class名称。
template<class T>