C++ 空类,默认产生哪些成员函数。

    默认构造函数、默认拷贝构造函数、默认析构函数、默认赋值运算符 这四个是我们通常大都知道的。但是除了这四个,还有两个,那就是取址运算符和 取址运算符 const

即总共有六个函数

    一个示例如下:

  1. 1: class Empty

  1. 2: 

  1. 3: {

  1. 4: 

  1. 5: public:

  1. 6: 

  1. 7: Empty(); // 缺省构造函数

  1. 8: 

  1. 9: Empty( const Empty& ); // 拷贝构造函数

  1. 10: 

  1. 11: ~Empty(); // 析构函数

  1. 12: 

  1. 13: Empty& operator=( const Empty& ); // 赋值运算符

  1. 14: 

  1. 15: Empty* operator&(); // 取址运算符

  1. 16: 

  1. 17: const Empty* operator&() const; // 取址运算符 const

  1. 18: 

  1. 19: };

  但是,C++默认生成的函数,只有在被需要的时候,才会产生。即当我们定义一个类,而不创建类的对象时,就不会创建类的构造函数、析构函数等。

 

1.对于一个类X,如果一个构造函数的第一个参数是下列之一

    a) X&

    b) const X&

    c) volatile X&

    d) const volatile X&

    且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数

    X::X(const X&); //是拷贝构造函数

    X::X(X&, int=1); //是拷贝构造函数

 

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&),由编译器根据上下文决定选择哪一个。

 

测试代码如下:

  1. 1: #include <iostream>

  1. 2: using namespace std;

  1. 3: 

  1. 4: class X {

  1. 5: public:

  1. 6: X() { cout << "X()" << endl;}

  1. 7: X(X& x, int a = 1) {cout << "X(X&)" << endl;}

  1. 8: X(const X& x) {cout << "const X(X&)" << endl;}

  1. 9: X(volatile X& x) {cout << "volatile X(X&)" << endl;}

  1. 10: };

  1. 11: 

  1. 12: int main(int argc, char** argv) {

  1. 13: X x1;

  1. 14: X x2(x1);

  1. 15: const X x3;

  1. 16: X x4(x3);

  1. 17: volatile X x5;

  1. 18: X x6(x55;

  1. 19: return 0;

  1. 20: }

运行结果:

而如果注释掉上面的8 和9行(即取消const 和volatile 拷贝构造函数),会编译错误,如下:

    默认拷贝构造函数的行为如下:

    默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造。

    拷贝构造函数对类中每一个数据成员执行成员拷贝(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>

              perator=( const T& ); // NOT copy ass't, T can't be X

        };

        原因很简单,成员函数模版并不改变语言的规则,而语言的规则说,如果程序需要一个拷贝构造函数而你没

有声明它,那么编译器会为你自动生成一个。所以成员函数模版并不会阻止编译器生成拷贝构造函数, 赋值运算

符重载也遵循同样的规则。(参见Effective C++ 3edition, Item45)

 

另外这些函数,只有在没有时,才会默认生成。而如果提供了声明,即使没有实现,也不会生成默认的函数。

因此我们通常用的方法是将拷贝构造和赋值设置为private而不实现,以禁止类的拷贝和赋值。

C++中的空类,默认产生哪些类成员函数?

C++ 空类,默认产生哪些成员函数的更多相关文章

  1. C++ 空类默认产生的类成员函数

    C++的空类有哪些成员函数:. 缺省构造函数.. 缺省拷贝构造函数.. 缺省析构函数.. 缺省赋值运算符.. 缺省取址运算符.. 缺省取址运算符 const.     注意:有些书上只是简单的介绍了前 ...

  2. 在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static

    在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static ! 在C语言中,我们使用pthread_create ...

  3. 4.6 C++抽象基类和纯虚成员函数

    参考:http://www.weixueyuan.net/view/6376.html 总结: 在C++中,可以通过抽象基类来实现公共接口 纯虚成员函数没有函数体,只有函数声明,在纯虚函数声明结尾加上 ...

  4. [C++]类的空指针调用成员函数后,会发生什么事?

    类的实例调用成员函数的原理 其实不管是通过对象实例或指针实例调用,其实底层调用的过程都是一样的,都是把当前对象的指针作为一个参数传递给被调用的成员函数.通过下面的相关实例代码进行检验: 实验的C++代 ...

  5. 【C++缺省函数】 空类默认产生的6个类成员函数

    1.缺省构造函数. 2.缺省拷贝构造函数. 3. 缺省析构函数. 4.缺省赋值运算符. 5.缺省取址运算符. 6. 缺省取址运算符 const. <span style="font-s ...

  6. 堆(stack) 之 c 和 c++模板实现(空类默认成员函数 初谈引用 内联函数)

    //stack 的基本操作 #include <iostream> using namespace std; const int maxn = 3; typedef struct Stac ...

  7. C++类的定义,成员函数的定义,对象的创建与使用

    类是一个模板,可用类生成一系列可用的实例.例如 int B就是生成了一个符合int的数据B,类也是一样,使用类名就可以直接生成一个实例, 该实例中包含类中所有的数据类型和对这些数据的操作方法. 首先, ...

  8. 类 this指针 const成员函数

    C++ Primer 第07章 类 7.1.2 ​Sales_data类的定义如下: #ifndef SALES_DATA_H #define SALES_DATA_H #include <st ...

  9. C++笔记007:易犯错误模型——类中为什么需要成员函数

    先看源码,在VS2010环境下无法编译通过,在VS2013环境下可以编译通过,并且可以运行,只是运行结果并不是我们期待的结果. 最初通过MyCircle类定义对象c1时,为对象分配内存空间,r没有初始 ...

随机推荐

  1. PNG文件格式

    PNG文件的组成 一个PNG文件可以看作是由多个数据块(chunk)部分组成,如同积木一样,一个数据块就是一个小积木,不同类型的积木组合搭建成了我们的PNG图像. PNG图像至少由文件署名域和三个关键 ...

  2. servlet 实践

    基础 当Servlet引擎收到一个请求,它将请求所有的细节汇编到一个HttpServletRequest对象.细节包括请求头部.URI.查询字符串和任意发送的参数等等.类似地,它初始化一个处理响应头部 ...

  3. java命令-jstack

    jstack用于生产java虚拟机当前时刻的线程快照.线程快照是当前java虚拟机内每一条线程正在执行的方法 堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,比如线程间死锁.死循环. ...

  4. jdbcTemplate查询结果为对象list

    RowMapper<WmsExpensesSettleEntity> rowMapper1=new BeanPropertyRowMapper<WmsExpensesSettleEn ...

  5. java中的成员变量、类变量,成员方法、类方法 属性和方法区别

    成员变量:包括实例变量和类变量,用static修饰的是类变量,不用static修饰的是实例变量,所有类的成员变量可以通过this来引用. 类变量:静态域,静态字段,或叫静态变量,它属于该类所有实例共有 ...

  6. 最新最全最详细的MacOS 10.14 Mojave黑苹果安装教程

    图文教程知乎地址:点击打开链接 视频教程B站地址:点击打开链接 微信公众号 地 址:点击打开链接 准备工作(工具包及镜像在后边) 一个8G以上的U盘(有的U盘标的是8G,实际只有7.X,实际容量小于7 ...

  7. 如何把EXCEL数据导入到SQL SERVER数据库中 (转)

    转:http://blog.csdn.net/jjp837661103/article/details/13509889 在我们完成一个项目开发之后,通常我们需要把客户的很多数据导入到数据库中,面对大 ...

  8. QTP学习笔记---datatable应用

    DataTable应用1.定位数据行 DataTable.GetSheet() 2.获取当前行 GetCurrentRow3.获取指定行的值 getValueByRow = DataTable.Get ...

  9. HTML5: HTML5 Web SQL 数据库

    ylbtech-HTML5: HTML5 Web SQL 数据库 1.返回顶部 1. HTML5 Web SQL 数据库 Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个 ...

  10. Java学习之接口

    接口作用:为类提供额外功能(方法) 一.接口定义 interface IDemo { ;//可以简写:int NUM=4; public abstract void show();//可以简写:voi ...