C++ 空类,默认产生哪些成员函数
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++ 空类默认产生的类成员函数
C++的空类有哪些成员函数:. 缺省构造函数.. 缺省拷贝构造函数.. 缺省析构函数.. 缺省赋值运算符.. 缺省取址运算符.. 缺省取址运算符 const. 注意:有些书上只是简单的介绍了前 ...
- 在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static
在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static ! 在C语言中,我们使用pthread_create ...
- 4.6 C++抽象基类和纯虚成员函数
参考:http://www.weixueyuan.net/view/6376.html 总结: 在C++中,可以通过抽象基类来实现公共接口 纯虚成员函数没有函数体,只有函数声明,在纯虚函数声明结尾加上 ...
- [C++]类的空指针调用成员函数后,会发生什么事?
类的实例调用成员函数的原理 其实不管是通过对象实例或指针实例调用,其实底层调用的过程都是一样的,都是把当前对象的指针作为一个参数传递给被调用的成员函数.通过下面的相关实例代码进行检验: 实验的C++代 ...
- 【C++缺省函数】 空类默认产生的6个类成员函数
1.缺省构造函数. 2.缺省拷贝构造函数. 3. 缺省析构函数. 4.缺省赋值运算符. 5.缺省取址运算符. 6. 缺省取址运算符 const. <span style="font-s ...
- 堆(stack) 之 c 和 c++模板实现(空类默认成员函数 初谈引用 内联函数)
//stack 的基本操作 #include <iostream> using namespace std; const int maxn = 3; typedef struct Stac ...
- C++类的定义,成员函数的定义,对象的创建与使用
类是一个模板,可用类生成一系列可用的实例.例如 int B就是生成了一个符合int的数据B,类也是一样,使用类名就可以直接生成一个实例, 该实例中包含类中所有的数据类型和对这些数据的操作方法. 首先, ...
- 类 this指针 const成员函数
C++ Primer 第07章 类 7.1.2 Sales_data类的定义如下: #ifndef SALES_DATA_H #define SALES_DATA_H #include <st ...
- C++笔记007:易犯错误模型——类中为什么需要成员函数
先看源码,在VS2010环境下无法编译通过,在VS2013环境下可以编译通过,并且可以运行,只是运行结果并不是我们期待的结果. 最初通过MyCircle类定义对象c1时,为对象分配内存空间,r没有初始 ...
随机推荐
- PNG文件格式
PNG文件的组成 一个PNG文件可以看作是由多个数据块(chunk)部分组成,如同积木一样,一个数据块就是一个小积木,不同类型的积木组合搭建成了我们的PNG图像. PNG图像至少由文件署名域和三个关键 ...
- servlet 实践
基础 当Servlet引擎收到一个请求,它将请求所有的细节汇编到一个HttpServletRequest对象.细节包括请求头部.URI.查询字符串和任意发送的参数等等.类似地,它初始化一个处理响应头部 ...
- java命令-jstack
jstack用于生产java虚拟机当前时刻的线程快照.线程快照是当前java虚拟机内每一条线程正在执行的方法 堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,比如线程间死锁.死循环. ...
- jdbcTemplate查询结果为对象list
RowMapper<WmsExpensesSettleEntity> rowMapper1=new BeanPropertyRowMapper<WmsExpensesSettleEn ...
- java中的成员变量、类变量,成员方法、类方法 属性和方法区别
成员变量:包括实例变量和类变量,用static修饰的是类变量,不用static修饰的是实例变量,所有类的成员变量可以通过this来引用. 类变量:静态域,静态字段,或叫静态变量,它属于该类所有实例共有 ...
- 最新最全最详细的MacOS 10.14 Mojave黑苹果安装教程
图文教程知乎地址:点击打开链接 视频教程B站地址:点击打开链接 微信公众号 地 址:点击打开链接 准备工作(工具包及镜像在后边) 一个8G以上的U盘(有的U盘标的是8G,实际只有7.X,实际容量小于7 ...
- 如何把EXCEL数据导入到SQL SERVER数据库中 (转)
转:http://blog.csdn.net/jjp837661103/article/details/13509889 在我们完成一个项目开发之后,通常我们需要把客户的很多数据导入到数据库中,面对大 ...
- QTP学习笔记---datatable应用
DataTable应用1.定位数据行 DataTable.GetSheet() 2.获取当前行 GetCurrentRow3.获取指定行的值 getValueByRow = DataTable.Get ...
- HTML5: HTML5 Web SQL 数据库
ylbtech-HTML5: HTML5 Web SQL 数据库 1.返回顶部 1. HTML5 Web SQL 数据库 Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个 ...
- Java学习之接口
接口作用:为类提供额外功能(方法) 一.接口定义 interface IDemo { ;//可以简写:int NUM=4; public abstract void show();//可以简写:voi ...