1:知识点1:在定义一个类时,我们可以显式或隐式的定义在此类型的对象拷贝、赋值、移动、销毁是做什么,主要通过五种特殊的成员函数来完成这些操作:拷贝构造函数、拷贝复制运算符、移动构造函数、移动复制运算符。析构函数
知识点2:拷贝和移动构造函数定义了当用同类型的一个对象初始化本对象时做什么。拷贝和移动赋值运算符定义了将一个对象赋予同类型的另一个对象时做什么。析构函数定义了当此类型对象销毁时的操作
知识点3:若一个类没有显式的定义这五个操作,编译器会自动为其定义缺失的操作,在定义一个类时,拷贝控制操作是非常的重要的
知识点4:拷贝构造函数:本身是一个构造函数,其参数是一个自身类类型的引用,且任何额外参数皆有默认值
知识点5:每个成员的类型决定了它的拷贝方式,对于类类型,将调用其拷贝构造函数进行拷贝,对于内置类型,则会直接拷贝,对于数组的拷贝是逐个元素的拷贝,若数组的元素是类类型,则使用拷贝构造函数来拷贝
知识点6:直接初始化:一对小括号加参数。拷贝初始化:等号右侧对象拷贝到正在创建的对象中,如果需要还需进行类型转换(拷贝初始化没有=号的情况:将一个对象作为实参传递给一个非引用类型的形参时、从一个返回类型非引用类型的函数返回一个对象、用花括号初始化列表初始化一个数组的元素或一个聚合类的成员)
知识点7:函数的调用中,非引用类型的参数都要进行拷贝初始化。非引用类型的返回值也会被用来初始化调用方的结果
见知识点
2:此为一个类的拷贝构造函数,作为函数其非引用类型的参数需要进行拷贝初始化,但拷贝初始化又要调用拷贝构造函数以拷贝实参,但为了拷贝实参又需要调用拷贝构造函数,无限循环。
3:StrBlob中元素复制,且智能指针计数加一。StrBlobStr中元素复制,弱指针复制不影响计数器
4:首先foo_bar函数的参数为非引用类型,需拷贝,使用拷贝构造函数、函数的返回类型非引用,也需要进行拷贝,使用拷贝构造函数。
在函数体中arg拷贝到local对象,global拷贝到heap对象,local、*heap拷贝到pa[4]中皆使用拷贝构造函数
local拷贝到*heap为拷贝赋值运算符
5:
Hasptr(const Hasptr& HP):*ps(new string *HP.ps),i(HP.i){}6:知识点1:拷贝复制运算符,其实就是一个名为 Operator= 的函数(operator后加表示要定义的运算符的符号),重载运算符,有返回类型和参数,返回类型通常是左侧运算符的引用
知识点2:若在类内未显式定义,则编译器会自动生成合成拷贝赋值运算符,它主要是将运算符右侧的所有非static成员赋给左侧元算对象对应成员(或是用来禁止该类型对象的赋值)
见知识点
7:所有成员的赋值会发生,两个StrBlob中智能指针所指对象内存相同,计数器加一,两个StrBlobPtr中弱指针所致对象内存相同,计数器不变。
8:相较于第五题,将赋值过程置于函数体内,而不是初始化列表,返回类型不同
HasPtr& operator= (const Hasptr& HP){ string *p = new string(*HP.ps);//new返回的是指向分配好内存、创建了对象的指针 delete ps;//首先删除原内存 ps = p; //赋值 i = HP.i; return *this;//返回值}9:知识点1:构造函数初始化对象的非static数据成员,析构函数释放对象所使用资源,并销毁对象的非static数据成员
知识点2:形式:波浪号加类名
知识点3:构造函数中,成员初始化是在函数体执行之前完成的,且按照他们在类内出现的顺序进行初始化,析构函数中,首先执行函数体,然后销毁成员,成员按照初始化顺序的逆序销毁,所以析构函数可以执行设计者想要的任何收尾工作,再销毁成员
知识点4:成员的销毁完全依赖于其本身的类型,类类型需要执行自身的析构函数,而内置类型则什么也不做(无析构函数)
知识点5:调用析构函数的情况:
1:变量离开作用域时被销毁
2:当对象被销毁,其成员被销毁
3:容器被销毁,成员被销毁
4:动态分配的对象,指针被delete时
5:临时对象,创建的完整表达式结束时
知识点6:合成析构函数—编译器自动生成的析构函数,基本上为空,或者被用来阻止对象被销毁
知识点7:析构函数体自身并不直接销毁成员,是在析构函数体执行完毕之后隐式的析构阶段中被销毁的
见知识点
10:所有对象的数据成员被销毁,智能指针的计数减一,所有对象的数据成员被销毁,弱指针不影响计数器
新闻热点
疑难解答
图片精选