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

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

即总共有六个函数

    一个示例如下:

   1: class Empty

   2:  

   3: {

   4:  

   5:   public:

   6:  

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

   8:  

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

  10:  

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

  12:  

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

  14:  

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

  16:  

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

  18:  

  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: #include <iostream>

   2: using namespace std;

   3:  

   4: class X {

   5:   public:

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

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

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

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

  10: };

  11:  

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

  13:   X x1;

  14:   X x2(x1);

  15:   const X x3;

  16:   X x4(x3);

  17:   volatile X x5;

  18:   X x6(x55;

  19:   return 0;                                                                                                               

  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. windows自动关机(任务计划程序 + exe文件)

    需求:windows系统自动关机 的需求: 相关工具:win10系统中,使用windows自带的任务计划程序 和 windows自带的关机 exe文件 完成此需求 exe文件位置:C:\Windows ...

  2. USB hub串口绑定

    方式一 1.查看串口信息 udevadm info /dev/ttyUSB0 2.创建配置文件 sudo vi /etc/udev/rules.d/com_port.rules ACTION==&qu ...

  3. 轻量级Spring定时任务(Spring-task)

    Spring3.0以后自主开发的定时任务工具,spring-task,可以将它比作一个轻量级的Quartz,而且使用起来很简单,除spring相关的包外不需要额外的包,而且支持注解和配置文件两种形式. ...

  4. go语言从例子开始之Example2.类型

    Go 拥有各值类型,包括字符串,整形,浮点型,布尔型等.下面是一些基本的例子. Example: values.go package main import "fmt" func ...

  5. solaris系统动态查看swap的使用情况

    root@tt # root@tt # prstat  -aPlease wait... PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU ...

  6. c++后台开发面试常见知识点总结(六)算法手写

    链表倒转  leetcode-206 连续子数组最大和问题(和最大的连续子序列的和)   leetcode-53 输出字符串中最长的回文子串长度?  leetcode-5 一个字符串,求最长无重复子串 ...

  7. boost pointer container

    1. boost::ptr_vector #include <boost/ptr_container/ptr_vector.hpp> #include <iostream> i ...

  8. Spring框架-经典的案例和demo,一些可以直接用于生产,使用atomikos来处理多数据源的一致性事务等

    Spring Examples Demo website:http://www.ityouknow.com/ 对Spring框架的学习,包括一些经典的案例和demo,一些可以直接用于生产. sprin ...

  9. React的contextType的使用方法简介

    上一篇介绍了Context的使用方法.但是Context会让组件变得不纯粹,因为依赖了全局变量.所以这决定了Context一般不会大规模的使用.所以一般在一个组件中使用一个Context就好. 由于C ...

  10. python 反转列表的3种方式

    转载自:https://blog.csdn.net/bookaswine/article/details/42468735 方式一:使用reversed()函数 a=[1,2,3,4,5,6,7,8, ...