关于C++类中的土著民:构造函数,复制构造函数,析构函数

我们初学C++时可能会对类的构造函数,复制构造函数,析构函数有点疑问。整理如下(个人见解,如有错误,还望指正。):

1.构造函数

根据构造函数的定义知它的作用是初始化类的数据成员或内嵌类的对象,所以它的参数表就应该是它要初始化的对象类型。构造函数分三类:默认构造函数、构造函数、委托构造函数。

默认构造函数

默认构造函数没有返回值,没有参数表,没有函数体,如果类内没有显式的定义构造函数,系统会自动生成默认构造函数,如果已经定义了构造函数,但仍需要默认构造函数,可以在默认构造函数参数表后加default:

Point() = default;

提示:即使已经定义了构造函数,最好也定义一个默认构造函数,以备不时之需。

构造函数

普通的构造函数有两种形式:带有初始化列表、不带初始化列表两种,一般情况下这两种没多大区别,但有几种特殊情况必须使用带初始化列表的形式:如果要初始化的成员是引用、const类型或者属于某种为提供默认构造函数的类类型时,必须通过构造函数的初始值列表进行初始化。对于这个:

class Point

{ public:

Point(int a,int b):x(a),y(b) {}

private:

int x,y;

};

如果主函数有如下语句:Point p = Point(1,2);既可以看成是强制类型转换,也可以看成构造函数的调用。不仅是类,甚至是内置数据类型,比如int、float、double等,如果有int a = int(3.14); 这样的语句,既可以看成强制类型转换,也可以看成int的构造函数的调用,有人会有疑问:int是数据类型,怎么会有构造函数?我想用Python中的工厂函数来解释比较贴切,形如int()在Python中称为工厂函数,听名字就知道,工厂就是大量生产的意思,就是生产int型数据的工厂。这样好理解了吧。

委托构造函数

委托构造函数并不常用,顾名思义,委托构造函数就是把一个构造函数的任务委托给另一个构造函数。委托构造函数和构造函数一样,有一个初始值列表和函数体比如:

class Point  //点类

{ public:

Point(int a,int b):x(a),y(b)  {} //带形参的构造函数

Point(): Point(0,0) {}     //委托构造函数,默认构造函数委托带有两个int型形参的构造函数初始化数据成员

private:

int x,y;

};

2.复制构造函数

复制构造函数的参数是本类对象的引用,复制构造,顾名思义,就是拿本类的对象初始化本类的另一个对象的喽,形参当然是本类对象的引用啦。类的继承也不例外,派生类的复制构造函数的参数也是派生类对象的引用,根据类型兼容规则,派生类的对象可以初始化基类对象,所以这样是允许的。但基类对象初始化派生类对象却是不安全的,因为派生类包含基类的成员(基类的构造函数、复制构造函数和析构函数除外),所以派生类的范围要大于基类。用一句话来说就是:大的可以初始化小的,但小的不能初始化大的(dynamic_cast类型转换也是这个道理)。

复制构造函数归根结底落脚点还是构造,有木有发现构造函数和复制构造函数长得很像,它们有很多共同之处。所以可以把复制构造函数看成构造函数的一种重载形式,区别就是它们的参数表不同,系统会根据实参的不同类型调用构造函数或者复制构造函数。

3.析构函数

析构函数非常简单,它没有返回值,没有参数表,没有函数体,函数名与类名相同,函数名前需要加一个~以便于默认构造函数区分开来。一般情况下我们不必太在意析构函数,但有一种情况需要注意,就是在实现类的多态性时最好要把基类和派生类的析构函数声明为虚函数,以便在使用动态内存时能正确释放申请的堆空间。

时间: 2024-12-29 23:28:17

关于C++类中的土著民:构造函数,复制构造函数,析构函数的相关文章

C++类中的特殊成员函数-------复制构造函数

在C++中存在一个特殊函数,他就是复制构造函数,假如我们有类A,如果有A a;A b=a;   在这种情况下利用A类变量a来给同是A类变量的b来赋值,这个时候类会使用复制构造函数,如果我们不显式声明复制构造函数,那么类将会调用默认的复制构造函数.下面的代码说明了这一情况,如果我们将类StringBad中的复制构造函数StringBad(StringBad &)去掉,那么count最后输出的结果会为复制(count为静态变量用来记录类StringBad的对象个数). main.cpp #inclu

构造函数复制构造函数经典问题

◆由于构造函数不能被继承,因此,派生类的构造函数中除了对派生类中数据成员进行初始化外,还必须通过调用直接基类的构造函数来对基类中数据成员初 始化,一般地将,对派生类中数据成员初始化放在该派生类构造函数的函数体内,而调用基类构造函数的基类中数据成员初始化放在该构造函数的成员初始化表中. 派生类构造函数的格式如下表示: <派生类构造函数名>(<参数表>) : <成员初始化表> { <派生类构造函数的函数体> } 其中,<派生类构造函数名>同该派生类的

复制构造函数(拷贝构造函数)

也许很多C++的初学者都知道什么是构造函数,但是对复制构造函数(copy constructor)却还很陌生.对于我来说,在写代码的时候能用得上复制构造函数的机会并不多,不过这并不说明复制构造函数没什么用,其实复制构造函数能解决一些我们常常会忽略的问题. 为了说明复制构造函数作用,我先说说我们在编程时会遇到的一些问题.对于C++中的函数,我们应该很熟悉了,因为平常经常使用:对于类的对象,我们也很熟悉,因为我们也经常写各种各样的类,使用各种各样的对象:对于指针的操作,我们也不陌生吧?嗯,如果你还不

C++ Primer 学习笔记_54_类与数据抽象 --复制构造函数、赋值操作符

复制控制 --复制构造函数.赋值操作符 引言: 当定义一个新类型时,需要显式或隐式地指定复制.赋值和撤销该类型的对象时会发生什么– 复制构造函数.赋值操作符和析构函数的作用!      复制构造函数:具有单个形参,该形参(常用const修饰)是对该类类型的引用.当定义一个新对象并用一个同类型的对象对它进行初始化时,将显式的使用复制构造函数:当将该类型的对象传递给函数或者从函数返回该类型的对象时,将隐式使用复制构造函数.     析构函数:作为构造函数的互补,当对象超出作用域或动态分配的对象被删除

类的六个默认成员函数-&gt;构造函数

在C++中当你创建一个空类时,编译器会默认声明一个default构造函数,copy构造函数,一个copy assignment操作符,一个析构函数.注意,编译器只声明,只有当这些函数被调用时,他们才会被创建. 举个栗子,当你写下 class Empty() {}; 实际上在编译器中为你实现了这样的代码 class Empty { Empty(){} Empty(const Empty& rhs){} ~Empty(){} Empty& operator=(const Empty&

C++学习基础六——复制构造函数和赋值操作符

1.什么是复制构造函数 复制构造函数:是构造函数,其只有一个参数,参数类型是所属类的类型,且参数是一个const引用. 作用:将本类的成员变量赋值为引用形参的成员变量. 2.什么是赋值操作符 赋值操作符:返回值是本类的引用类型,参数类型是所属类的类型,且参数是一个const引用. 作用与复制构造函数相同. 其声明如下: 1 Sales_item& operator=(const Sales_item& rig); 3.什么情况下需要我们自己实现复制构造函数和赋值操作符? 一般情况下,C++

函数重载与复制构造函数

函数重载与复制构造函数   一.函数重载 1.普通函数重载 用main函数多次重复调用一个相同名字但是不同类型的函数来处理不同类型的数据. 如 void func(int); void func(double); float func(float); void func(double); 2.成员函数的重载 我们可以将函数的重载推广到类的成员函数. Class  boy { Public: void  sum(); void  sum(int  x, int  y); } 二.函数的默认参数 在

何时调用C++复制构造函数和拷贝构造函数(转)

1. 何时调用复制构造函数 复制构造函数用于将一个对象复制到新创建的对象中.也就是说,它用于初始化过程中,而不是常规的赋值过程中.类的复制构造函数原型通常如下: class_name(const class_name&); 它接受一个指向类对象的常量引用作为参数.例如,String类的复制构造函数的原型如下: String(const String&); 新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用.这在很多情况下都可能发生,最常见的情况是将新对象显示地初始化为现有的对

【C/C++】复制构造函数、深复制浅复制

常见问题 Q1. 下面代码的输出结果是( )? 1 #include <iostream> 2 using namespace std; 3 4 class MyClass 5 { 6 public: 7 MyClass(int n) { number = n; } 8 MyClass(const MyClass &other) 9 { 10 number = other.number; 11 cout << "a "; 12 } 13 private: