C++11--20分钟了解C++11 (下)

20分钟了解C++11

9 override关键字 (虚函数使用)

 *
* 避免在派生类中意外地生成新函数
*/
// C++ 03
class Dog {
virtual void A(int);
virtual void B() const;
} class Yellowdog : public Dog {
virtual void A(float); // 生成一个新函数
virtual void B(); //生成一个新函数
} // C++ 11
class Dog {
virtual void A(int);
virtual void B() const;
void C();
} class Yellowdog : public Dog {
virtual void A(float) override; // Error: no function to override
virtual void B() override; // Error: no function to override
void C() override; // Error: not a virtual function
}

10 final (虚函数和类使用)


class Dog final { // 在类名后添加表示不能再从该类派生子类
...
}; class Dog {
virtual void bark() final; // 在虚函数后添加表示该函数不能再被覆写
};

11 编译器生成默认构造函数

class Dog {
Dog(int age) {}
}; Dog d1; // 错误:编译器不会自动生成默认构造函数,因为已经有构造函数了 // C++ 11:
class Dog {
Dog(int age);
Dog() = default; // 强制编译器生成默认构造函数
};

12 delete 禁用某些函数


class Dog {
Dog(int age) {}
} Dog a(2);
Dog b(3.0); // 3.0会从double类型转成int类型
a = b; // 编译器会生成赋值运算符 // C++ 11 手动禁用:
class Dog {
Dog(int age) {}
Dog(double ) = delete;
Dog& operator=(const Dog&) = delete;
}

13 constexpr 常量表达式

int arr[6];    //OK
int A() { return 3; }
int arr[A()+3]; // 编译错误 // C++ 11
constexpr int A() { return 3; } // 强制计算在编译时发生 int arr[A()+3]; // 生成一个大小为6的数组 // 利用constexpr写更快的程序
constexr int cubed(int x) { return x * x * x; } int y = cubed(1789); // 在编译时计算 //cubed()函数:
//1. 非常快,不消耗运行时计算
//2. 非常小,不占据二进制空间

14 新的字符串字面值

  // C++ 03:
char* a = "string"; // C++ 11:
char* a = u8"string"; // UTF-8 string.
char16_t* b = u"string"; // UTF-16 string.
char32_t* c = U"string"; // UTF-32 string.
char* d = R"string \\" // raw string.

15 lambda函数

cout << [](int x, int y){return x+y}(3,4) << endl;  // Output: 7
auto f = [](int x, int y) { return x+y; };
cout << f(3,4) << endl; // Output: 7 template<typename func>
void filter(func f, vector<int> arr) {
for (auto i: arr) {
if (f(i))
cout << i << " ";
}
} int main() {
vector<int> v = {1, 2, 3, 4, 5, 6 }; filter([](int x) {return (x>3);}, v); // Output: 4 5 6
...
filter([](int x) {return (x>2 && x<5);}, v); // Output: 3 4 int y = 4;
filter([&](int x) {return (x>y);}, v); // Output: 5 6
//注: [&] 告诉编译器要变量捕获
} // Lambda函数几乎像是一个语言的扩展,非常方便
// template
// for_nth_item

17 用户自定义的字面值


// C ++在很大程度上使用户定义的类型(类)与内置类型的行为相同.
// 用户自定义的字面值使其又往前迈出一步 //老的C++,不知道到底表示多长?
long double height = 3.4; // 在学校物理课的时候
height = 3.4cm;
ratio = 3.4cm / 2.1mm; // 为什么在编程时不这么做?
// 1. 语言不支持
// 2. 单位转换需要运行时开销 // C++ 11:
long double operator"" _cm(long double x) { return x * 10; }
long double operator"" _m(long double x) { return x * 1000; }
long double operator"" _mm(long double x) { return x; } int main() {
long double height = 3.4_cm;
cout << height << endl; // 34
cout << (height + 13.0_m) << endl; // 13034
cout << (130.0_mm / 13.0_m) << endl; // 0.01
} //注: 加constexpr使单位转换在编译时计算 // 限制: 只能用于以下参数类型:
char const*
unsigned long long
long double
char const*, std::size_t
wchar_t const*, std::size_t
char16_t const*, std::size_t
char32_t const*, std::size_t
// 返回值可以是任何类型 // 例子:
int operator"" _hex(char const* str, size_t l) {
// 将十六进制格式化字符串str转成int ret
return ret;
} int operator"" _oct(char const* str, size_t l) {
// 将格式化8进制字符串str转成 int ret
return ret;
} int main() {
cout << "FF"_hex << endl; // 255
cout << "40"_oct << endl; // 32
}

18 可变参数模板 Variadic Template

 *
* 可以接受任意个数的任意类型模板参数的模板
* 类和函数模板都可以是可变的
*/
template<typename... arg>
class BoTemplate; BoTemplate<float> t1;
BoTemplate<int, long, double, float> t2;
BoTemplate<int, std::vector<double>> t3; BoTemplate<> t4; // 可变参数和非可变参数组合
template<typename T, typename... arg>
class BoTemplate; BoTemplate<> t4; // Error
BoTemplate<int, long, double, float> t2; // OK // 定义一个默认模板参数
template<typename T = int, typename... arg>
class BoTemplate;

19 模板别名 Template Alias

  template<class T> class Dog { /* ... */ };
template<class T>
using DogVec = std::vector<T, Dog<T>>; DogVec<int> v; // 同: std::vector<int, Dog<int>>

20 decltype

 * 相当于GNU typeof
*/
const int& foo(); // 声明一个函数foo()
decltype(foo()) x1; // 类型是const int& struct S { double x; };
decltype(S::x) x2; // x2类型double auto s = make_shared<S>();
decltype(s->x) x3; // x3类型double int i;
decltype(i) x4; // x4类型int float f;
decltype(i + f) x5; // x5类型float // decltype对于模板泛型编程非常有用
template<type X, type Y>
void foo(X x, Y y) {
...
decltype(x+y) z;
...
} // 如果返回值要使用decltype?
template<type X, type Y>
decltype(x+y) goo(X x, Y y) { // 错误:x 和 y 未定义
return x + y;
} // auto和decltype组合实现具有尾随返回类型的模板
template<type X, type Y>
auto goo(X x, Y y) -> decltype(x+y) {
return x + y;
}
上一篇:Windows和Linux下通用的线程接口


下一篇:cdh5 hadoop redhat 本地仓库配置