苏州市住房和城乡建设局信息网站,建设银行招聘门户网站,数字营销沙盘大赛,文章内容网站系统概述 C 11中引入了许多简化编程工作的语法上的新特性#xff0c;我们暂且美其名曰#xff1a;“语法甜点”。书接上篇#xff0c;我们继续介绍C 11中的这些“语法甜点”#xff0c;也是第二篇关于“语法甜点”的文章。 语法甜点6#xff1a;模板右边双括号 在C 03中#…概述 C 11中引入了许多简化编程工作的语法上的新特性我们暂且美其名曰“语法甜点”。书接上篇我们继续介绍C 11中的这些“语法甜点”也是第二篇关于“语法甜点”的文章。 语法甜点6模板右边双括号 在C 03中vectorvectorint vctTemp是一个非法的表达式编译器会认为右边的是一个移位操作符因此必须修改为vectorvectorint vctTemp即在右边的两个中间添加一个空格。在C 11中这将不再是一个问题编译器将能够识别出右边的双括号是两个模板参数列表的结尾。 语法甜点7static_assert 静态断言static_assert由一个常量表达式和一个字符串构成。在编译期间将计算常量表达式的值如果为false字符串将作为错误信息输出。
#include iostream
using namespace std;int main()
{char cNumber 66;static_assert(sizeof(cNumber) 4, not an interger);return 0;
} 语法甜点8初始化列表 在引入C 11之前只有数组能使用初始化列表。在C 11中vector、list等各种容器以及string都可以使用初始化列表了。初始化列表对应的类为initializer_listvector、list等各种容器以及string之所以可以使用初始化列表是因为它们重载了参数类型为initializer_list的构造函数称为初始化列表构造函数和赋值函数称为初始化列表赋值函数。
#include iostream
#include vector
#include map
using namespace std;void Print(const initializer_listint ilData)
{for (auto a : ilData){cout a endl;}
}int main()
{vectorint vctNum {1, 2, 3, 4, 5};mapstring, string mapID2Name {{92001, Tom}, {92002, Mike}};string strText{Hello CSDN};Print({});Print({1, 2});Print({1, 2, 3, 4, 5});return 0;
} 语法甜点9默认或禁用函数 当我们定义了自己的带参数的构造函数时编译器将不再生成默认的构造函数如果此时想使用默认的构造函数则必须显式地声明并定义不带参数的构造函数。在C 11中我们可以使用default关键字来表明我们希望使用默认的构造函数。 类似的当我们不想外部使用编译器自动生成的构造函数或赋值函数时我们一般需要将其声明成protected或private的。在C 11中我们可以使用delete关键字来表明我们不希望编译器生成默认的构造函数或赋值函数。
class CPerson
{
public:CPerson() default;CPerson(const CPerson person) delete;
}; 另外delete的声明同时也是定义也能适用于非自带函数以禁止成员函数以特定的形参调用。
class CNoDouble
{void f(int i);void f(double) delete;
}; 若尝试以double的形参调用f()将会引发编译错误编译器不会自动将double形参转换为int再调用f()。 若要彻底禁止以非int的形参调用f()可以将delete与模板相结合。
class COnlyInt
{void f(int i);templateclass T void f(T) delete;
}; 语法甜点10继承的构造函数 当一个派生类的某个函数隐藏了基类中的某个同名函数时如果我们想在派生类中导出基类中的这个同名函数可以通过using Base::Func的方式将基类中的这个同名函数引入到派生类的作用域内。但该方法只对普通成员函数有效不能用于构造函数。 在C 11中如果派生类认为基类的构造函数已经足够则也可以使用using Base::Base的方式将基类的构造函数引入到派生类的作用域内。注意此时派生类中的成员变量并没有进行初始化所以应当对这些成员变量进行就地初始化。
#include iostream
#include string
using namespace std;class CBase
{
public:CBase(int nValue) : m_nValue(nValue){cout Base constructor with int endl;}CBase(double dValue) : m_nValue((int)(dValue * 10)){cout Base constructor with double endl;}private:int m_nValue;
};class CDerived : public CBase
{
public:// 使用 using 关键字引入基类的所有构造函数到派生类中using CBase::CBase;// 如果需要添加额外的成员变量或自定义构造函数可以继续定义CDerived(const string strText) : CBase((int)strText.size()){cout Derived constructor with string endl;}
};int main()
{// 调用 CBase(int) 构造函数CDerived d1(5);// 调用 CBase(double) 构造函数CDerived d2(3.14);// 调用 CDerived(const string ) 构造函数CDerived d3(Hello CSDN);return 0;
} 在上面的示例代码中CDerived类通过using CBase::CBase语句使得它可以直接使用CBase类中的所有公有和受保护的构造函数。这样在创建CDerived对象时可以根据传入的参数类型调用对应的基类构造函数来进行初始化。同时CDerived类还可以拥有自己的构造函数以处理新增成员变量的初始化和其他特殊逻辑。