C++构造函数、赋值构造函和拷贝构造函数

参考链接:https://blog.csdn.net/jin739738709/article/details/121679189

https://blog.csdn.net/beyond_cn/article/details/9021621

1.默认构造函数

任何可以不接受参数的构造函数都是默认构造函数。如果你创建了任何构造函数,编译器不会提供构造函数。

如果没有显示为类声明构造函数,编译器将生成一个不接受任何参数,也不执行任何操作的默认构造函数。编译器提供的默认构造函数不会为数据成员提供初始值,也就是不会把数据成员初始化为0或者NULL。

2.析构函数

析构函数在对象被销毁后完成清理工作并释放(在构造函数或对象的生命周期中)分配的资源或内存。析构函数总是与类同名,但在前面加上一个~。析构函数没有参数也没有返回值,所以一个类只能有一个析构函数。

3. 默认拷贝构造函数

每当创建对象的拷贝时,都将调用拷贝构造函数。

所有拷贝构造函数都接受一个参数:指向其所属类的对象的引用。将该引用声明为const是个好主意,因为拷贝构造函数不会修改传入的对象。例如:Cat(const Cat & cat);

Cat构造函数接受一个指向cat对象的const引用。

缺点:默认拷贝构造函数将作为参数传入的对象的每个成员变量复制到新对象的成员变量中。这被称为成员拷贝(浅拷贝)。

对大多数成员变量来说是可行的,但对于指向自由存储区中的对象的指针成员变量不可行。需要深拷贝解决。

成员浅拷贝只是将对象成员变量的值复制到另一个对象中,两个对象中的指针最后将指向同一个内存块。深拷贝将在堆中分配的值复制到新分配的内存中。

拷贝构造函数被调用的情况:

ref:https://blog.csdn.net/ituling/article/details/52303320

(1)定义新对象,并用已有对象初始化新对象时; 即执行语句“Cat B=A; ” 时(定义对象时使用赋值初始化);

(2)当对象直接作为参数传给函数时,函数将建立对象的临时拷贝,这个拷贝过程也将调同拷贝构造函数

例如: BOOL testfunc(Cat obj){             //针对obj的操作实际上是针对复制后的临时拷贝进行的        }

testfunc(A); //对象直接作为参数,拷贝函数将被调用;

(3)当函数中的局部对象被返回给函数调者时,也将建立此局部对象的一个临时拷贝,拷贝构造函数也将被调用 

    Cat func(){

         Cat   c; 

return   c;

    }  

此外,假设motto是一个String对象,则下面4种声明都将调用复制构造函数

ref:https://blog.csdn.net/qfturauyls/article/details/105778231

  String ditto(motto);

  String metoo = motto;

  String also = String(motto);

  String *pString = new String(motto);

4. 赋值构造函数

赋值构造函数是通过重载赋值操作符实现的,这种操作符的原型如下:Class_name& Class_name::operator=(const Class_name&);

例如:

CExample & CExample::operator = (const CExample& RightSides){

if( this == &rightsides)    //自身判断

nSize=RightSides.nSize; //复制常规成员

char *temp=new char [nSize]; //复制指针指向的内容

memcpy(temp,RightSides.pBuffer,nSize*sizeof (char ));

delete []pBuffer; //删除原指针指向内容   (将删除操作放在后面,避免X=X特殊情况下,内容的丢失)

pBuffer=temp;    //建立新指向

 return *this;

 }

 它接受并返回一个指向类对象的引用。

例如,String 类的赋值操作符的原型:String& String::operator=(const String&);

 将已有的对象赋给另一个对象时,将使用重载的赋值操作符:

  String headline1("test");

  String knot;

  knot = headline1;

-------------------

 注意:初始化对象时,并不一定会使用赋值操作符:String metoo = knot;

  这里,metoo是一个新创建的对象,被初始化为knot的值,此时使用复制构造函数。不过,正如前面指出的,实现时也可能分两步来处理这条语句:使用复制构造函数创建一个临时对象,然后通过赋值将临时对象的值复制到新对象中。这就是说,初始化总是会调用复制构造函数,而使用=操作符时也可能调用赋值操作符

全部评论

相关推荐

牛客5655:其他公司的面试(事)吗
点赞 评论 收藏
分享
评论
点赞
2
分享
牛客网
牛客企业服务