构造函数

来源:互联网 发布:上海数据交易中心 coo 编辑:程序博客网 时间:2024/06/05 00:09

构造函数的定义
1、构造函数是在创建对象时调用的函数,用来初始化数据成员
2、构造函数名与类名相同,非const,可以是explicit的
3,构造函数定义在内部是内联的,定义在外部是非内联的
4,显示定义一个构造函数编译器就不会提供默认的构造函数,但是当我们即需要默认构造函数也需要自己定义构造函数时可以使用=default

拷贝构造函数
定义:创建一个类对象的副本(把类的数据成员(非static数据成员)拷贝到正在创建的对象中)
1,第一个参数必须是自身类类型的引用,且额外的参数都有默认值
2,拷贝构造函数不能是explicit类型的
3,即使定义了一个拷贝构造函数编译器也会为我们合成一个拷贝构造函数,但是我们可以在参数列表后加上=delete来阻止拷贝

Nocopy(const Nocpy &)=delete;

4,当传递一个实参或返回一个值时,不能隐式的使用一个explicit的构造函数,对于一个explicit构造函数必须显示的使用

void f(vector<int>); //接受大小参数的构造函数是explicit的f(10);//错误:10->vector<int>(10),接受大小参数的构造函数是explicit的不支持一步类型转换。

5,如果类不定义自己的拷贝构造函数,将会使用合成的拷贝构造函数,如果类中含有指针类型的成员,那拷贝前与拷贝后两个指针将指向相同的内存,在析构时将会对指向的对象delete两次,因此会引发错误。在定义自己的拷贝构造函数时对新创建的对象分配一个新的内存

hasptr f(hsaptr hp)   //值传递,拷贝(假定未定义拷贝构造函数){   hasptr ret=hp; //把hp拷贝给ret;  return ret;    //ret与hp将会被释放(两者的指针指向相同的内存}

补充:直接初始化就是带括号,拷贝初始化就是带等号。直接初始化就是调用与参数匹配的构造函数,拷贝初始化就是调用拷贝构造函数

string  s("initialization");  //直接初始化string s2=s ;    //拷贝初始化

拷贝赋值元算符
定义:一个类可以控制其对象如何赋值。
如果一个类没有定义拷贝赋值运算符,编译器会生成成一个合成拷贝赋值运算符,用来将右侧对象的每一个非static成员赋值给左侧的运算对象。
1,赋值运算符必须定义为成员函数,左侧运算对象隐式地绑定到this指针上
2,返回值是一个指向左侧运算对象的引用

salsdata& salsdata::operator=(const salsdata&rhs){   mData1=rhs.mData1;  mData2=rhs.mData2;  ....  return *this;}

析构函数
定义:释放对象所占用的内存,并销毁对象的非static数据成员
1,类的成员函数,名字由”~类名 “组成,没有返回值不接受参数
2,执行函数体,逆序销毁数据成员
3,销毁一个类类型的对象会调用析构函数,但是内置类型没有析构函数,所以销毁一个内置类型的成员什么也不做。
注释:隐式销毁一个内置指针类型的成员,不会delete它指向的对象
对于一个动态分配的对象,当对指向它的指针应用delete时,对象被销毁,内置指针与智能指针都指向动态分配的对象
4,与普通指针不同,智能指针是类类型,销毁时会调用析构函数。
5,当指向对象的引用或指针离开作用域时,析构函数不会执行
6,析构函数并不直接销毁数据成员,成员是在析构函数体之后隐含的析构阶段被销毁的
7,合成的析构函数不会delete一个指针数据成员,因此需要定义一个析构函数来释放构造函数分配的内存

//p与p2都指向动态分配的对象 salsdata *p=new salsdata;//p是一个内置指针 auto p2=make_shared<salsdata>();//p2是一个智能指针 salsdata item(*p);//拷贝构造函数把p指向的对象拷贝到item中 vector<salsdata>vec;//创建一个vector容器来装载salsdata对象 vec.push_back(*p2);//把p2指向的对象拷贝到vec中 delete p;  //销毁p指向的对象 }推出局部作用域:对p2,item,vec调用析构函数   销毁p2会递减其引用计数,当引用计数为0时会调用析构函数   销毁vec时会销毁其元素

经验一般自己定义析构函数时也要定义拷贝构造函数与拷贝赋值运算符
自己定义析构函数说明类中含有指针成员,需要指定如何释放构造分配的内存(合成的析构函数不会删除指针数据成员),那么在拷贝时为了防止拷贝前后两个对象的指针都指向相同的内存就需要自己定义如何拷贝数据成员。

0 0
原创粉丝点击