C++ 的构造/析构/赋值/拷贝函数比较

转载 2008年10月03日 14:44:00
 构造函数、析构函数与赋值函数是每个类最基本的函数。每个类只有一个析构函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)和 多个赋值函数(除了同类的赋值以外,还有其他的赋值方法)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数,如
A(void);                    // 缺省的无参数构造函数
A(const A &a);              // 缺省的拷贝构造函数
~A(void);                   // 缺省的析构函数
A & operate =(const A &a); // 缺省的赋值函数

有几个需要注意的内容:
@ 构造函数与析构函数的另一个特别之处是没有返回值类型
@ 构造从类层次的最顶层的基类开始,在每一层中,首先调用基类的构造函数,然后调用成员对象的构造函数。析构则严格按照与构造相反的次序执行,在析构的时候,最低层的派生类的析构函数最开始被调用,然后调用每个基类的析构函数。
@ “缺省的拷贝构造函数”和“缺省的赋值函数”均采用“位拷贝”而非“值拷贝”的方式来实现,倘若类中含有指针变量,这两个函数注定将出错

下面通过例子进一步说明,


1.构造函数的初始化表
设存在两个类:
class A
{
     …
     A(
void);                // 无参数构造函数

     A(const A &other);      // 拷贝构造函数
     A & operate =( const A &other);  // 赋值函数
    virtual ~A(void);        //析构函数
};
class
B
{
public
:
     B(
const A &a);    // B的构造函数


private:   
     A   m_a;            
// 成员对象

};


下面面是B的构造函数的2个实现,其中第一个的类B的构造函数在其初始化表里调用了类A的拷贝构造函数,从而将成员对象m_a初始化;而第二个的B的构造 函数在函数体内用赋值的方式将成员对象m_a初始化。我们看到的只是一条赋值语句,但实际上B的构造函数干了两件事:先暗地里创建m_a对象(调用了A的 无参数构造函数),再调用类A的赋值函数,将参数a赋给m_a。
B::B(const A &a)
: m_a(a)
{
    …
}

B::B(
const A &
a)
{
     m_a
=
a;
     …
}



2.拷贝函数和构造函数的区别
拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。
String a(“hello”);
String b(“world”);
String c = a; // 调用了拷贝构造函数,最好写成 c(a);
c = b;            // 调用了赋值函数
本例中第三个语句的风格较差,宜改写成String c(a) 以区别于第四个语句。

如果我们实在不想编写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,可以将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。


3.析构函数与虚析构函数
基类的构造函数、析构函数、赋值函数都不能被派生类继承。如果类之间存在继承关系,在编写上述基本函数时应注意以下事项:
@ 派生类的构造函数应在其初始化表里调用基类的构造函数
@ 基类与派生类的析构函数应该为虚(即加virtual关键字)
#include <iostream>
class Base
{
public
:
    
virtual ~Base() { cout<< "~Base" <<
endl ; }
};
class Derived : public
Base
{
public
:
    
virtual ~Derived() { cout<< "~Derived" <<
endl ; }
};

void main(void
)
{
     Base
* pB = new Derived;  // upcast

    delete pB;
}



输出结果为:
       ~Derived
       ~Base
如果析构函数不为虚,那么输出结果为
       ~Base

示例说明:

编写类String的构造函数,析构函数,赋值函数.

class String{

     public:

            String(const char *str=NULL);

            String(const String &other);

            ~String(void);

            String& operate = (const String &other);

     private:

            char * m_data;

};

String::String(const char*str){

        if(str==NULL){

             m_data = new char[1];

             *m_data ='/0';

          }

          else{

               int length = strlen(str);

               m_data= new char[length+1];

               strcpy(m_data,str);

           }

}

String::String(const String &other){

           int length = strlen(other.m_data);

           m_data = new char[length+1];

           strcpy(m_data,other.m_data);

}

String::~String(void){

          delete [] m_data;

}

String & String::operate = (const String &other){

          if(this==&other)  //检查自赋值.

                 return *this;

           delete [] m_data; //释放原有的内存资源.

           int length = strlen(other.m_data);

           m_data = new char[length+1];

           strcpy(m_data,other.m_data);

            return *this;

}

    

深入C++的拷贝构造和赋值函数 (深拷贝,浅拷贝)

参考了:点击打开链接以及《高质量程序设计指南C++/C语言》 说明 拷贝构造函数是一种特殊的构造函数。相同类型的类对象是通过拷贝构造函数来完成整个复制过程的。 函数的名称必须和类名称一致。 它...
  • ywok526
  • ywok526
  • 2014年08月13日 11:54
  • 1123

GeekBand学习笔记:C++三大函数:拷贝构造、拷贝赋值、析构函数

GeekBand学习笔记:C++三大函数:拷贝构造、拷贝赋值、析构函数C++中的类分为两种:带指针的类和不带指针的类,在设计不带指针的类的时候,不需要这三个函数数,因为默认的函数已经足够用了。但是在设...
  • u013835861
  • u013835861
  • 2016年03月01日 12:18
  • 519

C++中构造函数,拷贝构造函数,析构函数

C++中默认构造函数就是没有形参的构造函数。准确的说法,按照《C++ Primer》中定义:只要定义一个对象时没有提供初始化式,就是用默认构造函数。为所有 的形参提供默认实参的构造函数也定义了默认构造...
  • u012501459
  • u012501459
  • 2015年03月09日 21:29
  • 1476

[读书笔记] 深入探索C++对象模型-第五章-构造、析构、拷贝语义学(中)

继续整理第五章的内容,关于对象复制的。  对于默认的拷贝赋值操作符,在如下情况下不会表现出按位拷贝(bitwise copy:关于按位拷贝,实际就是不使用拷贝构造函数或者拷贝赋值操作符,这里的不使用是...
  • beyongwang
  • beyongwang
  • 2016年09月22日 23:43
  • 344

C++中的拷贝构造,赋值和移动构造

在说明这几个名词时,我们需要定义一个测试类Person,Person类的测试环境为vs2013一般情况下,在对象声明时用拷贝构造函数对对象进行初始化(在编译器进行优化的时候也会使用移动构造函\ 数(在...
  • u010154685
  • u010154685
  • 2016年06月29日 21:16
  • 1498

C++ 的构造/析构/赋值/拷贝函数比较

构造函数、析构函数与赋值函数是每个类最基本的函数。每个类只有一个析构函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)和多个赋值函数(除了同类的赋值以外,还有其他的赋值方法)。...
  • lisamme
  • lisamme
  • 2009年02月08日 16:59
  • 202

C++ 的构造/析构/赋值/拷贝函数比较

构造函数、析构函数与赋值函数是每个类最基本的函数。每个类只有一个析构函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)和 多个赋值函数(除了同类的赋值以外,还有其他的赋值方法)...
  • Elegant_Design
  • Elegant_Design
  • 2007年09月03日 16:57
  • 899

深入理解C++类的构造函数与析构函数

在研究C++类的继承、派生、组合时,一直没有清晰地了解构造函数与析构函数的调用过程。本章通过点-线组合类,来深入分析组合类情况下,对象的构造与析构。 1.问题的引入 源代码: #include ...
  • shenziheng1
  • shenziheng1
  • 2016年07月13日 23:16
  • 1907

深度探索C++对象模型:5.构造、析构、拷贝语意学

第五章:构造、析构、拷贝语意学 考虑下面这个abstract base class声明: class Abstract_base{ public:     virtual ~Abstract_...
  • walkerkalr
  • walkerkalr
  • 2014年01月10日 11:36
  • 1027

【C++】深度探索C++对象模型之构造、析构、拷贝语意学

一、纯虚函数的存在 可以定义和调用一个pure virtual function, 不过只能被静态调用(invoked statitcally),不能经由虚拟机制调用 Abstract_base::i...
  • zone_programming
  • zone_programming
  • 2015年12月28日 21:41
  • 415
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ 的构造/析构/赋值/拷贝函数比较
举报原因:
原因补充:

(最多只允许输入30个字)