C++基础语法友元类和友元函数

本期是c++基础语法分享的第五节,今天给大家来分享一下:
(1)explicit(显式)关键字;
(2)friend 友元类和友元函数;
(3)using;
(4):: 范围解析运算符;
(5)enum 枚举类型;
(6)decltype;
那么我们接下来一起来看看吧!
explicit(显式)关键字
explicit 修饰构造函数时,可以防止隐式转换和复制初始化
explicit 修饰转换函数时,可以防止隐式转换,但 按语境转换 除外
explicit 使用
struct a{ a(int) { } operator bool() const { return true; }};
struct b{ explicit b(int) {} explicit operator bool() const { return true; }};
void doa(a a) {}
void dob(b b) {}
int main(){ a a1(1); // ok:直接初始化 a a2 = 1; // ok:复制初始化 a a3{ 1 }; // ok:直接列表初始化 a a4 = { 1 }; // ok:复制列表初始化 a a5 = (a)1; // ok:允许 static_cast 的显式转换 doa(1); // ok:允许从 int 到 a 的隐式转换 if (a1); // ok:使用转换函数 a::operator bool() 的从 a 到 bool 的隐式转换 bool a6(a1); // ok:使用转换函数 a::operator bool() 的从 a 到 bool 的隐式转换 bool a7 = a1; // ok:使用转换函数 a::operator bool() 的从 a 到 bool 的隐式转换 bool a8 = static_cast《bool》(a1); // ok :static_cast 进行直接初始化
b b1(1); // ok:直接初始化 b b2 = 1; // 错误:被 explicit 修饰构造函数的对象不可以复制初始化 b b3{ 1 }; // ok:直接列表初始化 b b4 = { 1 }; // 错误:被 explicit 修饰构造函数的对象不可以复制列表初始化 b b5 = (b)1; // ok:允许 static_cast 的显式转换 dob(1); // 错误:被 explicit 修饰构造函数的对象不可以从 int 到 b 的隐式转换 if (b1); // ok:被 explicit 修饰转换函数 b::operator bool() 的对象可以从 b 到 bool 的按语境转换 bool b6(b1); // ok:被 explicit 修饰转换函数 b::operator bool() 的对象可以从 b 到 bool 的按语境转换 bool b7 = b1; // 错误:被 explicit 修饰转换函数 b::operator bool() 的对象不可以隐式转换 bool b8 = static_cast《bool》(b1); // ok:static_cast 进行直接初始化
return 0;}
friend 友元类和友元函数
能访问私有成员
破坏封装性
友元关系不可传递
友元关系的单向性
友元声明的形式及数量不受限制
using
using 声明
一条 using 声明 语句一次只引入命名空间的一个成员。它使得我们可以清楚知道程序中所引用的到底是哪个名字。如:
using namespace_name::name;
构造函数的 using 声明
在 c++11 中,派生类能够重用其直接基类定义的构造函数。
class derived : base {public: using base::base; /* 。.. */};
如上 using 声明,对于基类的每个构造函数,编译器都生成一个与之对应(形参列表完全相同)的派生类构造函数。生成如下类型构造函数:
derived(parms) : base(args) { }
using 指示
using 指示 使得某个特定命名空间中所有名字都可见,这样我们就无需再为它们添加任何前缀限定符了。如:
using namespace_name name;
尽量少使用 using 指示 污染命名空间
一般说来,使用 using 命令比使用 using 编译命令更安全,这是由于它只导入了指定的名称。如果该名称与局部名称发生冲突,编译器将发出指示。using编译命令导入所有的名称,包括可能并不需要的名称。如果与局部名称发生冲突,则局部名称将覆盖名称空间版本,而编译器并不会发出警告。另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确知道添加了哪些名称。
using 使用
尽量少使用 using 指示
using namespace std;
应该多使用 using 声明
int x;std::cin 》》 x ;std::cout 《《 x 《《 std::endl;
或者
using std::cin;using std::cout;using std::endl;int x;cin 》》 x;cout 《《 x 《《 endl;
:: 范围解析运算符
分类
全局作用域符(::name):用于类型名称(类、类成员、成员函数、变量等)前,表示作用域为全局命名空间
类作用域符(class::name):用于表示指定类型的作用域范围是具体某个类的
命名空间作用域符(namespace::name):用于表示指定类型的作用域范围是具体某个命名空间的
:: 使用
int count = 11; // 全局(::)的 count
class a {public: static int count; // 类 a 的 count(a::count)};int a::count = 21;
void fun(){ int count = 31; // 初始化局部的 count 为 31 count = 32; // 设置局部的 count 的值为 32}
int main() { ::count = 12; // 测试 1:设置全局的 count 的值为 12
a::count = 22; // 测试 2:设置类 a 的 count 为 22
fun(); // 测试 3
return 0;}
enum 枚举类型
限定作用域的枚举类型
enum class open_modes { input, output, append };
不限定作用域的枚举类型
enum color { red, yellow, green };enum { floatprec = 6, doubleprec = 10 };
decltype
decltype 关键字用于检查实体的声明类型或表达式的类型及值分类。语法:
decltype ( expression )
decltype 使用
// 尾置返回允许我们在参数列表之后声明返回类型template 《typename it》auto fcn(it beg, it end) -》 decltype(*beg){ // 处理序列 return *beg; // 返回序列中一个元素的引用}// 为了使用模板参数成员,必须用 typenametemplate 《typename it》auto fcn2(it beg, it end) -》 typename remove_reference《decltype(*beg)》::type{ // 处理序列 return *beg; // 返回序列中一个元素的拷贝}


欧盟委员会RAPEX对一款国产LED灯串进行召回
沃尔沃、大众、日产,防碰撞系统性能大比拼!
2020年甚至未来机器人领域会是什么样子?
FPGA测试面临哪些挑战?测试方案是什么?
土壤墒情监测站建设方案是怎么样的?
C++基础语法友元类和友元函数
NEC建立起了不仅仅依赖于面部图像的进行识别的技术
马少峰:路灯和工矿灯的尴尬现状与未来猜想
仿真技术在我国电力工业中的发展及应用
山西省智能电力监控系统, 可视化能源管理系统
终于来了!深圳首条MEMS中试线落地!中国第一MEMS代工厂主导建设!
推荐系统中候选生成和冷启动挑战的研究
Call for Code已成为全球备受瞩目的最典型‘科技向善’平台
直线电机在数控机床中的应用!
腾讯进军自研芯片市场,研发CPU/AI处理器
ISM RF产品的无线链路预算表
利用开源平台即服务更快地部署作战人员应用
对三种最典型的电调滤波电路进行分析和研究
百度处于搜索引擎这一迄今为止人工智能规模最大的应用场景
11月力帆集团传统乘用车车产量为0辆,或将为吉利代工生产