C++学习之类的构造函数、析构函数

  在C++的类中,都会有一个或多个构造函数、一个析构函数、一个赋值运算操作符。即使我们自己定义的类中,没有显示定义它们,编译器也会声明一个默认构造函数、一个析构函数和一个赋值运算操作符。例如:

 1 //声明一个空类
 2 class Empty{};
 3
 4 //但是这个空类和下面这个类是等同的
 5 class Empty
 6 {
 7     Empty(){.....};     //默认构造函数
 8     Empty( const Empty & rhs ){......}      //复制构造函数
 9     ~Empty(){..........}    //析构函数
10
11     Empty operator * (const Empty & rhs){.........}
12 };

  值得注意的是,只有当这些函数被调用的时候,他们才会被编译器创建出来。

  如果我们已经声明了一个构造函数,那么编译器将不会再创建一个默认构造函数。

  下面来详细介绍一下构造函数和析构函数。

1.构造函数

  构造函数(constructor)是与类同名的特殊成员函数,主要用于初始化对象的数据成员。定义形式如下:

1 class  X
2 {
3   //  .......
4      X();    //无参构造函数
5      X(......);  //有参构造函数,构造函数支持重载
6
7 //   .........
8 } 

  

构造函数的声明和定义方法与类的其他成员函数相同,可以在类的内部定义构造函数,也可以先在类中声明构造函数,然后在类外进行定义。在类外定义构造函数的形式如下:

1 X :: X(.....)
2 {
3 //...........
4 }

  构造函数具有以下几个特点:

  (1)构造函数与类同名

  (2)构造函数没有返回类型,void也不行

  (3)构造函数可以被重载

  (4)构造函数由系统自动调用,不允许在程序中显示调用它

  (5)构造函数的调用时机是定义对象之后的第一时间,即构造函数是对象的第一个被调用的函数

  (6)定义对象数组或用new创建动态对象时,也要调用构造函数。但定义数组对象时,必须有无参构造函数

  (7)构造函数通常应定义为共有成员(当然也可以定义为私有的,但不能被类外部访问。单例模式就用到私有化的构造函数)

  同时还需注意一下几点:

  (1)构造函数初始化列表中的成员初始化次序与它们在类中声明的次序相同,与其在初始化列表中的次序无关。如:

1 Tdate::Tdate(int m , int d , int y):month(m),day(d),year(y){}
2 Tdate::Tdate(int m , int d , int y):year(y),month(m),day(d){}
3 Tdate::Tdate(int m , int d , int y):day(d),year(y),month(m){}
4 //以上三个构造函数完全相同

  (2)构造函数初始化列表先于构造函数体中的语句执行

  (3)以下类成员必须使用成员初始化列表进行初始化:常量成员、引用成员、类对象成员、派生类构造函数对基类构造函数的调用

1.1默认构造函数

  默认构造函数是指不需要显示提供参数的构造函数。在某些情况下,必须使用默认构造函数来定义对象(如对象数组)

  如果一个类没有定义任何构造函数,在需要时编译器将会为它生成一个默认构造函数,它只负责创建对象,不做任何初始化工作。

  在用默认构造函数创建对象时,如果创建的是全局对象或静态对象,则对象的位模式全为0(可以理解为将所有数据成员初始化为0);如果创建的是局部对象,不进行对象数据成员的初始化,对象数据成员是未知的。

  注意:只有在类没有定义任何构造函数时,系统才会产生默认构造函数。一旦定义了任何形式的构造函数,系统将不再产生默认构造函数。

  我们可以对默认构造函数进行重定义,来为对象的数据成员提供初始值。同时我们还可以为参数提供默认值。

1.2重载构造函数

  重载构造函数必须具有不同的函数原型(即参数个数、参数类型或参数次序不能完全相同)

1.3复制构造函数

  复制构造函数是一个特殊的构造函数,用于根据已存在的对象初始化一个新建对象。

  如果没有定义类的复制构造函数,在需要时,C++编译器将产生一个具有最小功能的默认复制构造函数,形式如:X::X(const X&){}

  默认复制构造函数以成员按位复制(bit-by-bit)的方式实现成员的复制。按位复制就是把一个对象各数据成员的值原样复制到目标对象中。在没有涉及指针类型的数据成员时,默认构造函数能够很好地工作。但是,当一个类有指针类型的数据成员时,默认复制构造函数常会产生指针悬挂问题。如果类存在指针类型的数据成员,就应该为他提供自定义的复制构造函数(也就是重载)

  注意:复制构造函数的参数常常是const类型的本类对象的引用(X::X(const X&){})

2.析构函数

  析构函数(destructor)是与类同名的另一个特殊成员函数,作用于构造函数相反,用于在对象生存期结束时完成对象的清理工作。

  析构函数的名字由“~”+“类名”构成,形式如下:

 1 class X
 2 {
 3    private:
 4    //............
 5   public:
 6      ~X();  //析构函数
 7      X();  //无参构造函数
 8      X(....);  // 有参重载的构造函数
 9 //.........
10 }

  析构函数具有以下特点

  (1)析构函数的名字是在类名前加上“~”,不能是其他名字

  (2)析构函数没有返回值类型(void也不行),没有参数表

  (3)析构函数不能重载,一个类只能有一个析构函数

  (4)析构函数只能由系统自动调用,不能再程序中显示调用析构函数

  (5)若有多个对象同时结束生存期,C++按照与调用构造函数相反的次序调用析构函数

  (6)每个类都应该有一个析构函数,如果没有显示定义析构函数,C++将产生一个最小化的默认析构函数(X::~X())

  (7)构造函数和析构函数都可以是inline函数

  (8)在通常情况下,析构函数应设置为公有成员

时间: 2024-10-10 09:03:33

C++学习之类的构造函数、析构函数的相关文章

C++反汇编第一讲,认识构造函数,析构函数,以及成员函数

C++反汇编第一讲,认识构造函数,析构函数,以及成员函数 以前说过在C系列下的汇编,怎么认识函数.那么现在是C++了,隐含有构造和析构函数 一丶认识构造函数 高级代码: class MyTest { public: MyTest(); ~MyTest(); public: DWORD m_dwTest; }; MyTest::MyTest() { printf("1111\r\n"); //构造的时候先打印 } MyTest::~MyTest() { printf("2222

C\C++ vector 构造函数 & 析构函数

#include <iostream> #include <vector> using namespace std; class Obj { public: Obj(void){cout<<"Obj(void)"<<" "<<countOne<<endl;countOne++;} Obj(int x){cout<<"Obj(int x)"<<"

c#学习3,构造函数

using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace 构造函数1{ class Program { static void Main(string[] args) { person p1 = new person(); person p2 = new person("tom"); person p3 = new person("emily&quo

【C/C++学院】(6)构造函数/析构函数/拷贝构造函数/深copy浅copy

1.构造函数 类的初始化即为构造函数.也为:隐式的初始化. 构造函数在对象初始化的时候,自动被调用.隐式的调用. 构造函数分为三种:有参构造函数.无参构造函数.拷贝构造函数. 有参构造函数调用有三种:括号法.等号法.手工法. #include <iostream> using namespace std; class Test { private: int m_a; public: Test()//无参构造函数 { } Test(const Test &obj)//拷贝构造函数 { }

C++基础知识---构造函数 &amp; 析构函数 &amp; 虚拟析构函数

问题: 类需要一个无参的构造函数么? 类需要一个析构函数么? 类的构造函数需要初始化所有的对象成员么? 类需要一个虚析构函数么? 有些类需要虚析构函数只是为了声明他们的析构函数是虚的.绝不会用作基类的类是不需要虚析构函数的:任何虚函数只在继承的情况下才有用.假设B为父类,D为子类,B何时需要一个虚析构函数?只有有人肯呢过会对实际指向D类型对象的B*指针执行delete表达式,你就需要给B加上一个虚析构函数,即使B和D都没有虚函数,这也是需要的 B* bp = new D; Delete bp; 

构造函数 析构函数

;构造函数 构造函数和类同名,无类型和返回值 构造函数可以重载 构造函数编译器在对象申请完内存地址空间之后帮你调用,如果有父类先一层层的调完父类的构造函数最后子类 ;析构函数 析构函数只调用一次 析构函数在出对象所属作用域之后立马被调用 析构函数无类型,返回值参数 西沟函数可以外部手工调用 ;拷贝构造函数 拷贝构造函数参数为引用参数 类& object 拷贝构造函数在发生对象拷贝的时候被调用,例如函数传参如果形参是对象类型就会发生,其他类型不会, (const 类& object) 如果实

构造函数 析构函数需要注意的

构造函数和析构函数¶ 构造函数¶ void __construct ([ mixed $args [, $... ]] ) PHP 5 允行开发者在一个类中定义一个方法作为构造函数.具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作. Note: 如果子类中定义了构造函数则不会隐式调用其父类的构造函数.要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct().如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继

c++类大四个默认函数-构造函数 析构函数 拷贝构造函数 赋值构造函数

每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数).对于任意一个类A,如果不编写上述函数,C++编译器将自动为A 产生四个缺省的函数,例如: A(void);//缺省的无参数构造函数 A(const A&a);//缺省的拷贝构造函数 -A();//缺省的析构函数 A&operator=(const A &a);//缺省的赋值构造函数 1).“缺省的拷贝构造函数”和“缺省的赋值函数”均采用“位拷贝”而非“值拷贝”的方式来实现,倘

C++ 中的类构造函数 &amp; 析构函数

类的构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行. 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void.构造函数可用于为某些成员变量设置初始值. 下面的实例有助于更好地理解构造函数的概念: 1 #include <iostream> 2 3 using namespace std; 4 5 class Line 6 { 7 public: 8 void setLength( double len ); 9 double getLe