`
weihe6666
  • 浏览: 443548 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

C++ 构造函数

    博客分类:
  • C++
阅读更多
最近看C++方面的书,让我更深入的理解了C++的构造函数。什么情况下调用默认构造函数,什么情况下调用拷贝构造函数以及什么情况下使用显示的初始化列表,初始化列表的初始化顺序,以及显示的初始化列表和拷贝构造函数的区别,为什么拷贝构造函数和赋值构造函数同时出现?

1.默认构造函数

如果我们没有定义自己的构造函数,编译时会自动调用默认构造函数来初始化类的对象。那么既然可以调用默认的构造函数,为何还要自己定义构造函数?我的理解是:如果想初始化类的数据成员为某些特定的值时,这时就需要自己定义构造函数,否则不需要。

2.拷贝构造函数

既然有自己定义的构造函数,为何还要用拷贝构造函数。但是当类的数据成员包含指针,即需要动态的申请内存时,这是就需要自己定义拷贝构造函数。因为如果没有拷贝构造函数动态的为每一个对象申请内存,而只是用默认的拷贝构造函数来初始化类的对象时,所有的类的对象的指针数据成员所指向的是同一块地址,也就是不同的指针但是指向的却是同一块内存,而没有开辟自己的内存,这样在程序结束时调用析构函数就会出现一个内存块多次释放的错误。

比如下面的例子:

class Matrix { 
public: 
   Matrix( int row, int col ) 
         : _row( row ), _col( col ) 
   { 
           // constructor allocates a resource 
           // note: no error checking is shown 
           _pmat = new double[ row * col ]; 
   } 

   ~Matrix() 
   { 
           // destructor frees the resource 
           delete [] _pmat; 
   } 

   // ... 

private: 
   int     _row, _col; 
   double *_pmat; 
};

int main()
{
  Matrix a(4,6);
  Matrix b = a;
  return 0;
}


Matrix a(4,6);利用自定义的构造函数初始化对象a,并为double*_pmat;动态申请了内存。
Matrix b = a;由于programm没有定义自己的拷贝构造函数,编译器会使用默认的拷贝构造函数,int     _row, _col; 都可以恰当的被初始化,可是double *_pmat; 的初始化就不同了,只是b._pmat = a._pmat,这样a._pmat和b._pmat指向同一块内存。当然他们在使用的时候没有问题,但是当编译器调用析构函数~Matrix() 时就会出现问题,先是b.~Matrix() 这是已经把a对象申请的地址释放了,但当调用a.~Matrix() 时,就会出现问题。

拷贝构造函数如何定义:

类名::类名(const 类名 & 对象)
{
}

例如:
Matrix::Matrix( const Matrix &rhs ) 
    : _row( rhs._row ), _col( rhs._col ) 
{  // create a "deep copy" of the array addressed by rhs._pmat 
   int elem_cnt = _row * _col; 
   _pmat = new double[ elem_cnt ]; 

   for ( int ix = 0; ix < elem_cnt; ++ix ]   //动态申请内存
         _pmat[ ix ] = rhs._pmat[ ix ]; 
} 



3.拷贝赋值构造函数

为何要使用赋值构造函数,已经有了默认构造函数、自定义构造函数、拷贝构造函数,为何还要拷贝构造函数。类也是一种类型,类似于int char,为了兼容C中的赋值操作符,比如 int a = 2.;int b; b = a; 类的对象也可以直接赋值,这就是赋值构造函数的作用。

但是赋值构造函数也有默认的构造函数,为何不用默认的构造函数,这个原因和拷贝构造函数类似,也是当类的成员函数需要动态申请内存时就需要使用自定义的赋值构造函数。

赋值构造函数如何定义:
类名 & 类名::operator=(const 类名 & rhs)
{
}
Matrix& Matrix:: 
operator=( const Matrix &rhs ) 
{ 
   if ( this != &rhs )   //防止自符值
   { 
        _row = rhs._row; _col = rhs._col; 
        int elem_cnt = _row * _col; 

        delete [] _pmat; 
        _pmat = new double[ elem_cnt ]; 
        for ( int ix = 0; ix < elem_cnt; ++ix ] 
              _pmat[ ix ] = rhs._pmat[ ix ]; 
   } 

   return *this; 
}; 


4.构造函数初始化列表

为何要使用初始化列表,直接在构造函数体内初始化数据成员不也一样吗?

构造函数初始化列表也成为显示的初始化数据成员,它不需要隐士的调用拷贝构造函数直接初始化,效率会高些,而在构造函数体内初始化数据成员则会隐士调用拷贝构造函数,效率会低些。


分享到:
评论

相关推荐

    C++构造函数初始化列表

    ### C++构造函数初始化列表详解 在C++编程语言中,构造函数是对象生命周期开始时自动调用的特殊成员函数,用于初始化对象的状态。构造函数初始化列表是C++中一个非常重要的特性,它允许程序员在对象创建时直接对类...

    c++构造函数小测验

    本次小测验的主题是C++构造函数的相关知识点,包括构造函数的种类、调用时机以及构造函数的实现方式等。 首先,我们看到给定的代码片段中出现了Student类和Sprite类的定义,这两个类都是C++中类的典型示例。Student...

    C++构造函数

    C++构造函数,拷贝构造函数,虚函数,派生类

    C++构造函数重载

    在C++编程语言中,构造函数是类的一个特殊成员函数,它的主要职责是初始化新创建的对象。当一个类有多个构造函数,每个函数具有不同的参数列表时,我们称这种情况为构造函数的重载(Overloaded Constructors)。这种...

    通讯录 c++ 构造函数 类

    在C++编程中,"通讯录 c++ 构造函数 类"这一主题涉及到对象导向编程中的核心概念,如类的设计、构造函数的使用以及数据成员和成员函数的管理。下面将详细解释这些知识点: 1. **类(Class)**: 类是C++中的一个...

    C++构造函数的剖析

    ### C++构造函数的深入解析 #### 一、引言 在C++中,构造函数是一种特殊的成员函数,用于初始化类的对象。它不仅展示了C++类机制的强大功能,还直接影响了编译器如何处理对象。本文将详细介绍构造函数的特征、分类...

    论C++构造函数中的不合理设计

    ### 论C++构造函数中的不合理设计 #### 概述 C++作为一种广泛使用的编程语言,在面向对象编程领域占据着重要地位。构造函数作为类的一部分,用于初始化对象的状态,是C++中非常重要的一种机制。然而,构造函数的...

    C++构造函数分类讲解

    C++构造函数分类讲解,常见的构造函数都有讲解,虽然讲解的不是很详细但是能有利于新手的记忆。

    2.1深入C++构造函数共3页.pdf.zip

    深入理解C++构造函数,我们首先会遇到默认构造函数。默认构造函数是没有任何参数的构造函数,它通常用来初始化那些没有特定初始值的成员变量。例如: ```cpp class MyClass { public: MyClass() { } // 默认构造...

    C++构造函数详解及显式调用构造函数.pdf

    C++ 构造函数详解及显式调用构造函数 C++ 中的构造函数是一种特殊的成员函数,用于初始化对象的数据成员。构造函数的名称与类名相同,且无返回类型。构造函数可以分为四种:无参数构造函数、一般构造函数、复制...

    C++构造函数与析构函数.pdf

    C++构造函数与析构函数.pdf C++构造函数是类中的特殊成员函数,主要用于对象的初始化和销毁。构造函数的主要作用是对类对象成员的初始化,使得类对象在创建时自动调用构造函数对成员变量进行赋值操作。 根据C++的...

    c++构造函数和析构函数,拷贝,重载

    根据给定的文件标题“C++构造函数和析构函数,拷贝,重载”以及描述“一道很好的习题代码,包含构造、析构、拷贝、重载”,我们可以了解到这段代码主要涉及到了C++中类的设计与实现,特别是构造函数、析构函数、拷贝...

    C++构造函数_析构函数和赋值操作符学习小结

    C++构造函数、析构函数和赋值操作符学习小结 C++ 构造函数、析构函数和赋值操作符是 C++ 编程语言中的基本组件,它们提供了对象的初始化、销毁和赋值操作。这些函数的正确性对整个类的正确性至关重要。 构造函数 ...

    C++构造函数与析构函数

    ### C++构造函数与析构函数详解 在学习面向对象编程的过程中,构造函数与析构函数是两个非常重要的概念。本文将围绕一个简单的股票信息类`Stock`来深入讲解这两个概念,并通过具体代码实例帮助理解。 #### 构造...

    c++构造函数实例质料

    在C++编程语言中,构造函数是类的一个特殊成员函数,它的主要作用是初始化新创建的对象。构造函数的名称与类名相同,且没有返回类型。在这个实例中,我们看到了两种不同类型的构造函数:无参数构造函数和带有参数的...

    C++构造函数[定义].pdf

    C++构造函数是类的一个特殊成员函数,它的主要任务是对类的实例进行初始化。当创建一个对象时,构造函数会被自动调用。构造函数的名字与类名相同,并且没有返回类型,即使它可能执行复杂的初始化操作。构造函数分为...

    包含构造函数和析构函数的C++程序

    ### 构造函数和析构函数在C++中的应用 #### 概述 构造函数与析构函数是C++编程语言中非常重要的概念,它们在类的实例化和销毁过程中扮演着关键角色。通过理解这些函数的工作原理及其作用,我们可以更好地控制对象...

    C++构造函数的调用顺序

    C++构造函数的调用顺序详解 C++中的构造函数调用顺序是一个非常重要的概念,它决定了对象的初始化顺序。本文将详细介绍C++构造函数的调用顺序,包括基类构造函数、内嵌成员对象的构造函数和派生类的构造函数体中的...

    C++构造函数、复制构造函数和析构函数专题(修订版).pdf

    C++构造函数、复制构造函数和析构函数专题(修订版).pdf

Global site tag (gtag.js) - Google Analytics