v4if / blog

:octocat: 用issues写博客,记录点滴
34 stars 7 forks source link

Modern C++ #5

Open v4if opened 7 years ago

v4if commented 7 years ago

C++11

vector<int> v = {3, 4, 1, 9}; // Calling initializer_list constructor

// auto type
for (auto it = vec.begin(); it != vec.end(); ++it) {
  cout << (*it) << endl;
}
auto a = 6; // integer
auto b = 9.6; // double

// foreach
for (int i : v) {  // works on any class that has begin() and end()
  cout << i ;    // readonly access
}
for (auto& i : v) {
  i++;  // changes the values in v
}

// nullptr
void foo(int i) {cout << "foo_int" << endl;}
void foo(char* pc) {cout << "foo_char*" << endl;}
int main() {
  foo(NULL);  // 歧义
  foo(nullptr); // call foo(char*)
}

// enum class
// c++ 03
enum apple {green_a, red_a};
// c++ 11
enum class apple {green, red};
apple a = apple::green;

// static_assert
// run-time assert
assert(myPointer != NULL);
// compile time assert ( C++ 11 )
static_assert(sizeof(int) == 4);

// Delegating Constrctor
// C++ 03
class dog {
  init() {...};
public:
  dog() {init();}
  dog(int a) {init(); doOtherThings();}
};
// C++ 11
class dog {
public: 
  dog() {...}
  dog(int a) : dog() {...} // dog() has to be called first
};

// virtual override [compile check]

// final (for virtual function and for class)

// Compiler Generated Default Constructor, eg: dog(){}

// delete
dog& operator=(const dog&) = delete

char* a = u8"string"; // define an UTF-8 string 

// lanbda function
cout << [](int x, int y) {return x + y} (3, 4) << endl; // 7

Rvalue Reference

void printInt(int& i) {cout << "lvalue reference: " << i << endl;}
void printInt(int&& i) {cout << "rvalue reference: " << i << endl;}
int main() {
  int a = 5; // lvalue
  int& b = a; // lvalue reference
  int&& c;  // rvalue reference

  printInt(a); // Call printInt(int& i)
  printInt(6); // Call printInt(int&& i)
}
void foo(X x);
void foo_by_ref(X& x);
void main() {
  X x;
  foo_by_ref(x); // Call no constructor
  foo(x); // Call copy constructor
}
v4if commented 7 years ago

C++开发者都应该使用的10个C++11特性

v4if commented 7 years ago

概括的讲,凡是能够取地址的可以称之为左值,反之称之为右值,C++中并没有对左值和右值给出明确的定义,从其解决手段来看类似上面的定义,当然我们还可以定义为:有名字的对象为左值,没有名字的对象为右值。

std::move可以将一个左值转化为右值引用触发移动语义

template<typename T> 
decltype(auto) move(T&& param)
{
    using ReturnType = remove_reference_t<T>&&;
    return static_cast<ReturnType>(param);
}

// 触发move语义,src被掏空了
string(std::string&& src)
{
    data = src.data;
    src.data = nullptr;
}

通常用于转移对象的所有权 右值通常都是临时的,所以可以随意修改;如果知道某个参数的右值,就可以将其看作为一个临时存储或窃取内容,也不影响程序的正确性 例如指针的转移是通过移动,而非拷贝

/*
虽然右值引用参数绑定了右值,不过在函数内部,会当做左值来处理
**/
void do_stuff(X&& x_) {
  X a(x_); // 拷贝
  X b(std::move(x_)); // 移动
}
v4if commented 7 years ago

追踪返回类型

template<typename T1, typename T2>
auto sum(T1& t1, T2& t2) -> decltype(t1 + t2) {
    return t1 + t2;
}

auto占位符和->return_type是构成追踪返回类型函数的两个基本元素,追踪返回类型的函数和普通函数的声明最大区别在于返回类型的后置

v4if commented 7 years ago

有缺陷的枚举类型,具名的enum类型的名字,以及enum成员的名字都是全局可见的,因此枚举类型会污染全局变量 为了解决这一问题,可以对枚举类型进行封装

class Type{
public:
    enum type{general, light, medium, heavy};
};

强枚举类型

enum class Type{general, light, medium, heavy};

// 强作用域
Type::light;
v4if commented 7 years ago

unique_ptr与所指对象的内存绑定紧密,不能与其他unique_ptr类型的指针对象共享所指对象的内存,只能够通过move进行所有权的转移

shared_ptr允许过个该智能指针共享的拥有同一堆分配对象的内存,在实现上采用了引用计数

weak_ptr可以指向shared_ptr指针指向的对象内存,却不拥有该内存。而使用weak_ptr成员lock,则可返回其指向内存的一个shared_ptr对象,且在所指向对象内存无效时,返回指针空值(nullptr),因此可以验证shared_ptr智能指针的有效性

void check(weak_ptr<int>& wp) {
    shared_ptr<int> sp = wp.lock();
    if (sp != nullptr) 
        cout << "still " << *sp << endl;
    else 
        cout << "pointer is invalid." << endl; 
}
v4if commented 7 years ago

lambda对于按值方式传递的捕捉列表,其传递的值在lambda函数定义的时候就已经决定了。而按引用传递的捕捉列表变量,其传递的值等于lambda函数调用时的值。

int j = 12;
auto by_val_lambda = [=] {return j  + 1;}
auto by_ref_lambda = [&] {return j  + 1;}
std::cout << "by_val_lambda: " << by_val_lambda() << std::endl;
std::cout << "by_ref_lambda: " << by_ref_lambda() << std::endl;

j++;
std::cout << "by_val_lambda: " << by_val_lambda() << std::endl;
std::cout << "by_ref_lambda: " << by_ref_lambda() << std::endl;

/*
by_val_lambda: 13
by_ref_lambda: 13
by_val_lambda: 13
by_ref_lambda: 14
 */