C++并发编程(附录A)[ 默认函数关键字-03]
作者:互联网
author:
- luixiao1223
title: 附录A
A.3 Default functions
需要default的原因
default关键字用于标定编译器自动生成的函数.你之所以要标定这些函数的原因有以下几点.
-
改变默认函数的属性.因为默认函数是public.如果你想改成private或者protected.那么使用default关键字可以
-
更好的文档标注性.如果你想告诉client用户.默认构造函数已经足够了.你可以标定一个default
-
强制compiler给你n生成默认函数.(在有的情况下编译器选择拒绝生成,所以你加default让编译器强制生成.)
- 比如用户自定义了一个构造函数,编译器就会拒绝生成一个默认构造函数.
- 去掉参数的默认构拷贝构造函数的const属性
- 对默认析构函数加入virtual属性.
class Y
{
private:
Y() = default; // 改变访问属性
public:
Y(Y&) = default; //去掉参数const属性
Y& operator=(const Y&) = default; //为了代码清晰的标注.
protected:
virtual ~Y() = default; // 添加virtual属性
};
编译器默认生成的函数比用户自定义函数好在哪里
第一种不同
- 含有,trivial构造,trivial析构函数,trivial拷贝构造函数.以及trivial赋值操作符.可以被memcpy,memmove直接处理.
- 在constexpr函数中使用的literal
types.这些types一定要含有trivial(构造,拷贝和析构). - 具备trivial(拷贝,构造,赋值)可以用在union中.并且
- classes 具有trivial赋值操作符的可以应用在 std::atomic<>模板里面.
第二种不同
具备trivial属性的函数可以这样用
struct aggregate
{
aggregate() = default;
aggregate(aggregate const&) = default;
int a;
double b;
};
aggregate x={42,3.141}; // 这里就是集体赋值的方法
第三种不同
第三种不同非常的隐蔽.而且只针对默认构造函数.
struct X
{
int a;
};
X x1;// x1.a has an indeterminate value
X x2 = X();// x2.a == 0
struct X
{
int a;
};
void func()
{
X x1;
X x2 = X();
cout<<x1.a<<endl; //-1352207808
cout<<x2.a<<endl; //0
}
int main(int argc, char *argv[])
{
func();
return 0;
}
- 不同的编译器,会有不同的处理方法.
- 如果你写了一个自己的构造函数.你就失去了这个属性.但是如果你的函数也没有初始化它.也会发生未定义行为.
X::X():a(){}//a==0 always.
X::X():a(42){}//a==42 always.
X::X(){}//如果x是static,则a==0.如果x是non-static(a是未定义).
但是如果你force那个构造函数为default可以避免上面的问题.
struct X
{
int a;
X()=default;
};
void func()
{
X x1;
X x2 = X();
cout<<x1.a<<endl; // 0 这下都初始化了.
cout<<x2.a<<endl; // 0
}
int main(int argc, char *argv[])
{
func();
return 0;
}
atomic类型特别需要注意这一点.所以你最好加上default.
标签:03,函数,default,编程,C++,编译器,默认,trivial,构造函数 来源: https://blog.csdn.net/luixiao1220/article/details/104673061