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没有初始 ...
随机推荐
- SSH工具
SSH是什么:SSH是一种网络协议,用于计算机之间的加密登录 应用:用来连接远程服务器 适用人员:需要操作服务器的程序员,linux管理员等 需要的基础知识: http://www.ee. ...
- 关于Django路由层简单笔记
Django—路由层 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个U ...
- TextView点击后背景颜色、文字颜色改变(转)
转自:http://blog.csdn.net/u013278940/article/details/51152655 TextView本没有点击效果,故为实现点击后文字颜色改变和背景改变,需要写se ...
- c++while控制语句
while语句结构:while(condition){ statement; } condition 表示返回值是true or false 如果返回的一直是true则statement语句则一直执行 ...
- easyui记录
var rows = top.$("#queryDetailGrid").datagird("getRows"); //获取datagird所有行 top.$( ...
- Math.random()详解
Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值,是Java语言常用代码.例如:double a=Math.random()*(3-1)+1,设置 ...
- 前端解析Markdown
目录 前端解析Markdown 1.使用strapdown 1.1.下载 1.2.使用 2.使用marked(配合highlightjs) 2.1.下载 2.2.使用 3.使用mdjs(配合highl ...
- Mybatis基于XML配置SQL映射器(二)
Mybatis之XML注解 之前已经讲到通过 mybatis-generator 生成mapper映射接口和相关的映射配置文件: 下面我们将详细的讲解具体内容 首先我们新建映射接口文档 sysUse ...
- CF1061E Politics E. Politics 解题报告
CF1061E Politics E. Politics 考虑利用树的性质,因为是子树问题,所以放到dfs序上. 只考虑一个树,问题是每个区间选恰好\(k\)个.因为区间其实是子树,所以区间要么包含, ...
- 【git】如何ignore一个文件的更改又保留其初始版本
参考: https://compiledsuccessfully.dev/git-skip-worktree/ https://stackoverflow.com/questions/9794931/ ...