1、临时对象
比如:
A a;
a=A(1); //A(1)就是个临时对象
会自动的销毁
应用之一----防函数
template <typename T> class print { public: void operator()(const T& a) { cout<<a<<endl; } }; int main() { vector<int> m={0,1,2}; for_each(m.begin(),m.end(),print<int>()); //print<int>()就是个临时对象,随着for_each的结束自动销毁
}
2、静态常量整数成员在class中直接初始化
template <typename T> class print { public: static const int av=5; static const char ac='a'; };
3、内存模型
c++11引入了多线程,多线程读写同一变量需要使用同步机制,最常见的同步机制就是std::mutex
和std::atomic
。然而,从性能角度看,通常使用std::atomic
会获得更好的性能。原子类型的操作可以指定下述6种模型的中的一种
enum memory_order{ memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst }
读操作:memory_order_acquire, memory_order_consume
写操作:memory_order_release
读-修改-写操作:memory_order_acq_rel, memory_order_seq_cst
C++11中有3种不同类型的同步语义和执行序列约束:
1. 顺序一致性(Sequential consistency):对应的内存模型是memory_order_seq_cst
2.请求-释放(Acquire-release):对应的内存模型是memory_order_consume,memory_order_acquire(load()),memory_order_release(store()),memory_order_acq_rel
3.松散型(非严格约束。Relaxed):对应的内存模型是memory_order_relaxed
例子:
#include <thread> #include <atomic> #include <cassert> #include <string> std::atomic<bool> ready{ false }; int data = 0; void producer() { data = 100; // A ready.store(true, std::memory_order_release); // B } void consumer() { while (!ready.load(std::memory_order_acquire)) // C ; assert(data == 100); // never failed // D } int main() { std::thread t1(producer); std::thread t2(consumer); t1.join(); t2.join(); return 0; }
4、std::move()的适用场景(转)https://www.zhihu.com/question/57048704/answer/151446405
User create_user(const std::string &username, const std::string &password) { User user(username, password); validate_and_save_to_db(user); return user; } void signup(const std::string &username, const std::string &password) { auto new_user = create_user(username, password); login(user); }
比如上面的这个代码,create_user创建先创建了一个user,然后返回时又把user赋值给new_user,这个赋值会copy user里面的内容,如果user很大的话(很有可能user里面存了很多信息,比如username这种string的类型),这样太慢(copy string可能还需要多做一次malloc)。
使用user move可以减少copy的花销
一般情况下,当create_user里面的逻辑不复杂时会做优化,称为copy elision
那到底什么时候应该move,什么时候应该依靠copy elision呢?
通常主流的编译器都会100% copy elision以下两种情况:
1. URVO(Unnamed Return Value Optimization):函数的所有执行路径都返回同一个类型的匿名变量
2. NRVO(Named Return Value Optimization):函数的所有路径都返回同一个非匿名变量
如果程序员编码时显式地使用了std::move()函数来返回,编译器则不会做此项优化,这样反而会造成额外开销