c语言中default的用法
C语言是一门实践性和动手能力要求很高的大学主干课程,但是C语言实验课的教学一直不受重视,教学效果也不太理想。下面小编就跟你们详细介绍下c语言中default的用法,希望对你们有用。
c语言中default的用法如下:
一、类中的默认函数
a.类中默认的成员函数
1.默认构造函数
2.默认析构函数
3.拷贝构造函数
4.拷贝赋值函数
5.移动构造函数
6.移动拷贝函数
b.类中自定义的操作符函数
ator
ator&
ator&&
ator*
ator->
ator->*
ator new
ator
同时C++规定,一旦程序员实现了这些函数的自定义版本,则编译器不会再自动生产默认版本。注意只是不自动生成默认版本,当然还是可手动生成默认版本的。当我们自己定义了待参数的构造函数时,我们最好是声明不带参数的版本以完成无参的变量初始化,此时编译是不会再自动提供默认的无参版本了。我们可以通过使用关键字default来控制默认构造函数的生成,显式地指示编译器生成该函数的默认版本。比如:
classMyClass
{
public:
MyClass()=default; //同时提供默认版本和带参版本,类型是POD的
MyClass(inti):data(i){}
private:
int data;
};
有些时候我们希望限制默认函数的生成。典型的是禁止使用拷贝构造函数,以往的做法是将拷贝构造函数声明为private的并不提供实现,这样当拷贝构造对象时编译不能通过,C++11则使用关键字显式指示编译器不生成函数的默认版本。比如:
classMyClass
{
public:
MyClass()=default;
MyClass(constMyClass& )=;
......
}
当然,一旦函数被过了,那么重载该函数也是非法的,该函数我们习惯上称为删除函数。
二、default和的其他用途
上面我们已经看到在类中我们可用default和修饰成员函数,使之成为缺省函数或者删除函数,在类的外面,default可以在类定义之外修饰成员函数,比如:
classMyClass
{
public:
MyClass()=default;
MyClass() &operator=(constMyClass& );
);
//在类的定义外用default来指明缺省函数版本
inlineMyClass&MyClass::operator=(constMyClass& )=default;
还可以MyClass&MyClass::operator=(constMyClass& )=default;但是这种类外定义合成的成员就不是内联函数。
与=default 不同,=必须出现在函数的第一次声明中。因为一个默认的`成员只影响为这个成员生成的代码,因此=default 直到编译生成代码时才需要,而编译器必须早早知道一个函数是否是删除的,以便禁止试图使用它的操作。
一般情况下,析构函数不能定义为删除的,因为如果析构函数被删除,就无法删除此类型的对象了。对于一个删除了析构函数的类型,编译器将不允许定义该类型的变量或创建该类型的临时对象,而且如果一个类有某个成员的类型删除了析构函数,也不能定义该类的变量或临时对象,因为一个成员的析构函数是删除的,则该成员无法销毁,包含它的类也就没法销毁。虽然对于删除了析构函数的类型,我们不能定义这种类型的变量或成员但可以动态分配这种类型的对象,比如:
StructNoDtor{
NoDtor()=default;
~NoDtor()=default;
};
NoDtor *P=new NoDtor();//正确,但是我能 P
但是有时析构函数也是可以的,这样做的目的是我们在指定内存位置进行内存分配时并不需要析构函数来完成对象级别的清理,这时我们可显示删除析构函数来限制自定义类型在栈上或者静态的构造。
关于的显式删除,并非局限于成员函数,比如:
voidFunc(inti){};
void Func(char c)=; //显式删除char版本
int main()
{
Func(3);
Func('c’); //无法编译通过
return 0;
}
这里因为Func的char版本已经被删除,故Func('c')会编译失败。由此我们也知default是只局限作用于类的部分成员函数的。于是我们还可用来避免不必要的隐式数据类型转换。比如:
classMyClass
{
public:
MyClass(inti){};
MyClsss(char c)=; //删除char版本的构造函数
};
void Fun(MyClass m){}
int main()
{
Func(3);
Func('a'); //编译不能通过
MyClassm1(3);
MyClass m2('a'); //编译不能通过
}
这是因为char版本的构造函数被删除后,试图从char构造MyClass对象的方式是不允许的了。但去掉这句的函数删除后,编译器会隐式的将a转换为整型使得编译通过,调用的是整型构造函数,这可能并不是你所想要的。
但是如果这样:
classMyClass
{
public:
MyClass(inti){};
explicit MyClsss(char c)=; //删除explicit的char版本的构造函数
};
void Fun(MyClass m){}
int main()
{
Func(3);
Func('a'); //编译可通过
MyClassm1(3);
MyClass m2('a'); //编译不能通过
}
将构造函数explicit后,构造函数一样的还是不能发生char的构造,因为char构造版本被删除了,但在Func的调用中,编译器会尝试将c转换为int,即Func(a')会调用一次MyClass(int )构造,顺利通过编译。于是我们不提倡explicit和混用。对与普通函数也有类型的效果。
的用法还包括删除operator new操作符,编码在堆上分配该类的对象
如:void* operator new(std::size_t)=;
合成的拷贝控制成员可能是删除的,如果一个类有数据成员不能默认构造、拷贝、复制或销毁,则对应的成员函数将被定义为删除的。因此:
如果类的某个成员的析构函数是删除的或不可访问的,那么类的合成析构函数被定义为删除的。
如果类的某个成员的拷贝构造函数是删除的或不可访问的,则类的合成拷贝构造函数也被定义为删除的。
如果类的某个成员的拷贝赋值运算符是删除的或不可访问的,或是类有一个const的或引用成员,则类的合成拷贝赋值运算符被定义为删除的。
如果类的某个成员的析构函数是删除的或不可访问的,或是类有一个引用成员,它没有类内初始化器,或是类有一个const成员,它没有类内初始化器且其类型未显示定义默认构造函数,则该类的默认构造函数被定义为删除的
-
C语言的指针类型讲解
C语言的指针类型包括两方面的信息:一是地址,存放在指针变量中;二是类型信息,下面是小编为大家整理的C语言的指针类型讲解,欢迎参考~指针存储了内存的地址,同时指针是有类型的,如int*,float*,那么,一个自然的猜想就是指针变量应该存储这两方面的信息:地址和指针类型,比如,就...
-
2017年计算机C语言试题
2017年计算机C语言试题1应当随时学习,学习一切;应该集中全力,以求知道得更多,知道一切。以下是小编为大家搜索整理的计算机C语言试题,希望对大家有所帮助!更多精彩内容请及时关注我们应届毕业生考试网!1、下列数据结构中,属于非线性结构的是A、双向链表B、循环链表C...
-
C语言学习攻略
导语:C语言作为最流行的程序设计语言,是任何一个计算机专业及其爱好者们都必须掌握的一门编程语言。下面就由小编为大家介绍一下C语言学习攻略,欢迎大家阅读!一、C语言学习中存在的问题(一)基础薄弱,无法适应C语言学习的课程通常安排在大一,这个时候,学生们刚刚进入...
-
C语言scanf函数应用问题解答
C语言的输入是由系统提供的库函数完成的。scanf函数是C语言中最常用且功能最强的输入函数,但该函数如使用不慎,就会出现错误或得不到预想的结果。以下结果都是基于VC++6.0运行环境。一、格式说明符和输入项的三对应(类型、个数、顺序)scanf函数格式中的格式说明(“%...
相关文章
- TOEFL词汇:accumulated
- 英语美文:Olympic Fund Scratchcard Launched
- C语言中的小数(float,double)
- C语言double和float 实例分析用法
- An easy but difficult choice英语作文
- 雅思阅读模拟试题:Sun's fickle heart may leave us cold
- 英语短文:City Life Compared with Rural Life
- The world Cup Football Final英语作文
- Cultural differences英语作文
- 英语《Module 6 Unit 1 You can play football well》的教案设计