深入C++拷贝构造函数的总结详解

拷贝构造函数是C++最基础的概念之一,大家自认为对拷贝构造函数了解么?请大家先回答一下三个问题:
1. 以下函数哪个是拷贝构造函数,为什么?
X::X(const X&);  
X::X(X);  
X::X(X&, int a=1);  
X::X(X&, int a=1, b=2); 
2. 一个类中可以存在多于一个的拷贝构造函数吗?
3. 写出以下程序段的输出结果, 并说明为什么? 如果你都能回答无误的话,那么你已经对拷贝构造函数有了相当的了解。
 
#include <iostream> 
#include <string>    
struct X {  
  template<typename T>  
  X( T& ) { std::cout << "This is ctor." << std::endl; }

template<typename T>  
    X& operator=( T& ) { std::cout << "This is ctor." << std::endl; }  
};

void main() {  
  X a(5);  
  X b(10.5);  
  X c = a;  
  c = b;  
}

解答如下:
1. 对于一个类X,如果一个构造函数的第一个参数是下列之一:
    a) X&
    b) const X&
    c) volatile X&
    d) const volatile X&
    且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数.
    X::X(const X&);  //是拷贝构造函数  
    X::X(X&, int=1); //是拷贝构造函数 
    X::X(X&, int a=1, b=2);  //是拷贝构造函数 

2.类中可以存在超过一个拷贝构造函数,
class X {     
public:     
  X(const X&);     
  X(X&);            // OK  
}; 
注意,如果一个类中只存在一个参数为X&的拷贝构造函数,那么就不能使用const X或volatile X的对象实行拷贝初始化.
class X {  
public:  
  X();  
  X(X&);  
};

const X cx;  
X x = cx;    // error  
如果一个类中没有定义拷贝构造函数,那么编译器会自动产生一个默认的拷贝构造函数.这个默认的参数可能为X::X(const X&)或X::X(X&),由编译器根据上下文决定选择哪一个.
默认拷贝构造函数的行为如下:默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造.拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise Copy)的动作.
 a)如果数据成员为某一个类的实例,那么调用此类的拷贝构造函数.
 b)如果数据成员是一个数组,对数组的每一个执行按位拷贝.
 c)如果数据成员是一个数量,如int,double,那么调用系统内建的赋值运算符对其进行赋值.

3.  拷贝构造函数不能由成员函数模版生成.
struct X {  
    template<typename T>  
    X( const T& );    // NOT copy ctor, T can't be X

template<typename T>  
    operator=( const T& );  // NOT copy ass't, T can't be X  
};

原因很简单,成员函数模版并不改变语言的规则,而语言的规则说,如果程序需要一个拷贝构造函数而你没有声明它,那么编译器会为你自动生成一个. 所以成员函数模版并不会阻止编译器生成拷贝构造函数, 赋值运算符重载也遵循同样的规则

(0)

相关推荐

  • C++浅拷贝与深拷贝及引用计数分析

    C++浅拷贝与深拷贝及引用计数分析 在C++开发中,经常遇到的一个问题就是与指针相关的内存管理问题,稍有不慎,就会造成内存泄露.内存破坏等严重的问题.不像Java一样,没有指针这个概念,所以也就不必担心与指针相关的一系列问题,但C++不同,从C语言沿袭下来的指针是其一大特点,我们常常要使用new/delete来动态管理内存,那么问题来了,特别是伴随着C++的继承机制,如野指针.无效指针使用.内存泄露.double free.堆碎片等等,这些问题就像地雷一样,一不小心就会踩那么几颗. 先来谈一下C

  • 浅谈C++的浅拷贝出现的错误

    之前看一些资料提到浅拷贝的问题,即在复制对象时,只是对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝.如果对象中存在动态成员,如指针,那么仅仅做浅拷贝是不够的,并且容易引发错误,最经典的例子: #include <iostream> #include <stdio.h> using namespace std; class A{ public: A(){m_p = new int(10);}; ~A(){cout << "destructio

  • 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结

    1 . 用同一个类的源对象构造一个目标对象时,会调用拷贝构造函数来构造目标对象,如果没有定义拷贝构造函数,将调用类的默认拷贝函数来构造目标对象.2 . 当一个函数的返回值为一个类的对象时,如果在调用函数中,没有定义一个对象来接收这个返回对象值,会用返回一个临时对象保存返回对象的值.在被调用函数结束时,这个临时对象被销毁.而当调用函数中有一个接受对象时,就将返回对象赋值给接收对象,这个返回对象在调用函数结束时调用析构函数.3. 当类有一个带有一个参数的构造函数时,可以用这个参数同类型的数据初始化这

  • C++拷贝构造函数(深拷贝与浅拷贝)详解

    对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. 复制代码 代码如下: #include <iostream>using namespace std; class CExample {private:    int a;public:    CExample(int b)    { a=b;}    void Show ()    {       

  • 深入理解C/C++中的写时拷贝

    写时拷贝 何为写时拷贝? 前面我说过深拷贝浅拷贝,今天我们来探究一下写时拷贝.深拷贝是补充了浅拷贝的不足,写时拷贝其实也就是补充一点深拷贝的不足.其实写时拷贝的意思就是: 当你读取到这个空间的时候,并不会开辟出一个一模一样的空间出来给你,当你真正需要拷贝的时候,那么他就会开辟出空间给你.也就是拖延版的深拷贝. 写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数减一(

  • c++中深浅拷贝以及写时拷贝的实现示例代码

    本文主要给大家介绍了关于c++中深浅拷贝及写时拷贝实现的相关内容,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍: 一:浅拷贝&深拷贝 浅拷贝:在拷贝构造的时候,直接将原内容的地址交给要拷贝的类,两个类共同指向一片空间.但是存在很大的缺陷:①一旦对s2进行操作,s1的内容也会改变:②析构时先析构s2,再析构s1,但是由于s1,s2指向同一片空间,会导致一片空间的二次析构导致出错. 深拷贝:通过开辟和源空间大小相同的空间并将内容拷贝下来再进行操作.不论是否对s2进行操作,都会拷贝一片相

  • C++编程析构函数拷贝构造函数使用示例详解

    目录 构造函数 析构函数 拷贝构造之深拷贝和浅拷贝 深浅拷贝区别 首先定义一个类进行操作. class MM { public: protected: int year; string name; } 构造函数在类中默认有一个无参的构造函数 默认的构造函数为 类名(){}:这个构造函数 如果直接写了构造函数那么这个构造函数将会没有 构造函数 class MM { public: //MM() {};//无参构造函数 MM(int year, string name) :year(year), n

  • C++实现拷贝构造函数的方法详解

    目录 引入 一.什么是拷贝构造函数 二.什么情况下使用拷贝构造函数 三.使用拷贝构造函数需要注意什么 四.深拷贝浅拷贝 4.1 浅拷贝 4.2 深拷贝 引入 对于普通类型的对象来说,他们之间的复制很简单: int a = 10;int b = a; 但是对于类对象来说,其中会存在许多的成员变量. #include <iostream> using namespace std; class CExample { private: int a; public: //构造函数 CExample(in

  • C++中拷贝构造函数的总结详解

    1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了.(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数.百度百科上是这样说的:拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化.其唯一的参数(对象的引用)是不可变的(const类型).此函数经常用在函数调用时用户定义类型的值传递及返回. 2.拷贝构造函数的形式 复制代码 代码如下: Class X{public: X(); X(const

  • C++中拷贝构造函数的应用详解

    一.C++中拷贝构造函数的定义: 有一个参数的类型是其类类型的构造函数是为拷贝构造函数. 如下所示: X::X( const X& x); Y::Y( const Y& y, int =0 ); //可以是多参数形式,但其第二个即后继参数都有一个默认值 二.拷贝构造函数的应用: 当一个类对象以另一个同类实体作为初值时,大部分情况下会调用拷贝构造函数. 一般是这三种具体情况: 1.显式地以一个类对象作为另一个类对象的初值,形如X xx=x; 2.当类对象被作为参数交给函数时. 3.当函数返回

  • 深入C++拷贝构造函数的总结详解

    拷贝构造函数是C++最基础的概念之一,大家自认为对拷贝构造函数了解么?请大家先回答一下三个问题:1. 以下函数哪个是拷贝构造函数,为什么?X::X(const X&);   X::X(X);   X::X(X&, int a=1);   X::X(X&, int a=1, b=2);  2. 一个类中可以存在多于一个的拷贝构造函数吗?3. 写出以下程序段的输出结果, 并说明为什么? 如果你都能回答无误的话,那么你已经对拷贝构造函数有了相当的了解. #include <iost

  • C++ 中构造函数的实例详解

    C++ 中构造函数的实例详解 c++构造函数的知识在各种c++教材上已有介绍,不过初学者往往不太注意观察和总结其中各种构造函数的特点和用法,故在此我根据自己的c++编程经验总结了一下c++中各种构造函数的特点,并附上例子,希望对初学者有所帮助. 1. 构造函数是干什么的 class Counter { public: // 类Counter的构造函数 // 特点:以类名作为函数名,无返回类型 Counter() { m_value = 0; } private: // 数据成员 int m_va

  • C++类与对象深入之构造函数与析构函数详解

    目录 对象的初始化和清理 一:构造函数 1.1:构造函数的特性 1.2:构造函数的分类 二:析构函数 2.1:概念 2.2:特性 三:拷贝构造函数 3.1:概念 3.2:特性 3.3:拷贝构造函数调用时机 3.4:构造函数调用规则 对象的初始化和清理 生活中我们买的电子产品都基本会有出厂设置,在某一天我们不用时候也会删除一些自己信息数据保证安全.C++中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置. 一:构造函数 对象的初始化和清理也是两个非常重要的安全问题,一个

  • C++类继承之子类调用父类的构造函数的实例详解

    C++类继承之子类调用父类的构造函数的实例详解 父类HttpUtil: #pragma once #include <windows.h> #include <string> using namespace std; class HttpUtil { private: LPVOID hInternet; LPVOID hConnect; LPVOID hRequest; protected: wchar_t * mHostName; short mPort; string send

  • java static块和构造函数的实例详解

    java static块和构造函数的实例详解 构造函数不写时,若该类继续了某个类则会默认集成父类的构造函数. 构造函数在实例化类时执行内部, Object object = new Object(); static 块在每次加载该类的时候都会执行内部. 如下例: package org.webServiceClass; import javax.jws.WebMethod; public class WebSerivceTest { private static int i = 1; WebSe

  • Java 重载、重写、构造函数的实例详解

    Java 重载.重写.构造函数的实例详解 方法重写 1.重写只能出现在继承关系之中.当一个类继承它的父类方法时,都有机会重写该父类的方法.一个特例是父类的方法被标识为final.重写的主要优点是能够定义某个子类型特有的行为. class Animal { public void eat(){ System.out.println ("Animal is eating."); } } class Horse extends Animal{ public void eat(){ Syste

随机推荐