杂碎知识点

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::mutexstd::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;
}

4std::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()函数来返回,编译器则不会做此项优化,这样反而会造成额外开销

posted @ 2021-05-11 20:21  Z9Y1J5  阅读(50)  评论(0编辑  收藏  举报