- 用户自定义自面类型。第一次看到支持这个,很是吃惊!
- 如果字面量为整形数,那么字面量操作符只可接受unsigned long long。
- 如果字面为浮点数时,则字面可以接受的是long double;
- 如果字面量为字符串,则字面量操作符函数只可接受const char*,和size_t为参数,此size_t由编译器自动传入值。
- 如果字面量为字符,则字面量操作符函数只可一个char为参数。
#include <iostream> #include <cctype> using namespace std; void operator "" _C(char t) { cout <<(char) toupper(t)<<endl; } void operator "" _S(const char* t,size_t n) { //此处n为隐式直接传入,不需要在显示指定,其根据传入字符串长度,由编译器传入 int i =0; while(i < n) { cout << (char)toupper(*(t+i++)); } cout << endl; } void operator "" _I(unsigned long long i) { cout << "this is a long long !"<<endl; } void operator "" _F(long double t) { cout << "in double long F"<<endl; } int main() { "ddd mfdfdafjda,fdfd"_S;//DDD MFDFDAFJDA,FDFD 3456789876543_I;//this is a long long ! 'v'_C;//V 3.44_F;//in double long F }
- 可以有返回值,所以,这个很是方便用于赋值。
- 尽量在后缀之前添加_,若不添加编译器会有警告。
- opeartor "" 和符后之后应有空格,且我们只能定义后缀,不能定义前缀。
- 原生态字符串的支持,类似于c#中@字符串
#include <iostream> #include <cctype> using namespace std; int main() { char* c = R"(hello \n zaijian)"; cout << c; }
- 这个当然也可结合字符串前缀来使用,如u8,U,u,其前缀分别是u8R,UR,uR
- 枚举类型
- 在c++中枚举类型是一个奇怪的问题,就是具名的enum类型的名字,以及enum的名字都是全局可见的。如
这二者在c++中会编译时报错 erro redeclareation.enum type{a,b,}; enum category{a,b};
- 当然,我们可以通过namespace来分割两个枚举类型的,但这个解决方案也容易出错,当然我们可以通过类的方式封装枚举,这样可能会较好的解决这个问题,但太麻烦了。
- 在c++11中提出了强类型枚举可以较好的解决这个问题,其声明在enum后添加class说明即可。其优点:
- 强作用域 ,即强类型枚举枚举成员的名称不会输出到其父类作用域空间
- 转换限制,强类型枚举成员的值不可以与整型隐式地相互转换。
- 可以指定底层类型。默认为int型实现,但也可以显示指定底导类型。
#include <iostream> using namespace std; enum class type : char {a=1,b=127}; enum class catagory{a,b}; void func (type b){ cout <<sizeof(b); } int main() { //func(a); 报错,必须显示传入 func(type::a); }
- 在c++中枚举类型是一个奇怪的问题,就是具名的enum类型的名字,以及enum的名字都是全局可见的。如
- 在c++11后,联合体对类型的限制取消。原要求其类型必须是pod,而现在无此要求。可以像一个类型一样来定义联合,但必须自定义其相关的类的构造。
#include <iostream> #include <string> using namespace std; union r{ double x; string t; public : r(){ new (&t) string; } ~r(){ t.~string(); } }; int main() { r a; }
- 当然,我们可以给匿名union通过其他手段给予值,特别是当其内是完全类型时。此时这样的为可以称为 union like class
从这个例程可以看出的是如果我们不定义析构函数,则会报错,原因是由于其析构函数是被定义为删除的,具体分析,其主要原因是匿名联合体中采用了string这个非Pod类型,但由于我们采用了匿名的联合体,union难以显示定义其析构函数,故若在类中不定义析构函数,则将析构函数将定义为delete,而我们显示定义类的析构函数,需要针对匿名联合体中非pod的类型string作为定义析构。#include <iostream> #include <string> using namespace std; struct student{ int age; bool agenda; student(bool g,int a):age(a),agenda(g){} }; class qq{ public: enum class type {student,native,foreigner}; qq(bool g,int a):s(g,a){ t = type::student; } qq(int i):id(i){ t = type::native; } qq(string a):name(a){ t = type::foreigner; } ~qq(){ if(t == type::foreigner){ name.~string(); } } private: type t; union{ student s; int id; string name; }; }; int main() { qq(true,4); qq("polly"); }