Andy Niu �����ĵ�

Andy Niu

Andy Niu Help  1.0.0.0
ModernCPP

变量

 CPP遍历的方法汇总
 
 CPP11的thread
 
 move操作
 

详细描述

变量说明

CPP11的thread
1、先看C++98的线程测试代码
    #include <pthread.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    using namespace std;
    
    void* TestThread1(void*);
    
    int main(int argc, char* argv[])
    {
        pthread_t hThread;
        pthread_attr_t pAttr;
        pthread_attr_init(&pAttr);
        pthread_attr_setdetachstate(&pAttr,PTHREAD_CREATE_DETACHED);
        pthread_create(&hThread, &pAttr, TestThread1, NULL);
    
        printf("主线程:你好帅!!!!\n");
        getchar();
        return 0;
    }
    
    void* TestThread1(void*)
    {
        sleep(5);
        exit(0);
    }
2、编译,运行如下:
    root@ubuntu:/home/disk1/CPP_2/TestThread# g++ -o main_98 main_98.cpp -lpthread
    root@ubuntu:/home/disk1/CPP_2/TestThread# ./main_98
3、C++11的线程测试代码
    #include <thread>
    #include <unistd.h>
    using namespace std;
    
    void TestThread1();
    
    int main(int argc, char* argv[])
    {
        thread t1(TestThread1);
        t1.detach();
        printf("主线程:你好帅!!!!\n");
        getchar();
        return 0;
    }
    
    void TestThread1()
    {
        sleep(5);
        exit(0);
    }
4、编译,运行如下:
    root@ubuntu:/home/disk1/CPP_2/TestThread# g++ -o main_11 main_11.cpp -lpthread     
    In file included from /usr/include/c++/4.8/thread:35:0,
                    from main_11.cpp:1:
    /usr/include/c++/4.8/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
    #error This file requires compiler and library support for the \
    ^
    main_11.cpp: In function ‘int main(int, char**)’:
    main_11.cpp:9:5: error: ‘thread’ was not declared in this scope
        thread t1(TestThread1);
    编译报错,使用C++11的thread,需要添加选项 -std=c++11
5、再次测试如下:
    root@ubuntu:/home/disk1/CPP_2/TestThread# g++ -o main_11 main_11.cpp -std=c++11 -lpthread
    root@ubuntu:/home/disk1/CPP_2/TestThread# ./main_11
    terminate called after throwing an instance of 'std::system_error'
        what():  Enable multithreading to use std::thread: Operation not permitted
    Aborted (core dumped)
6、运行报错,查了一下资料,链接pthread的时候,必须去掉 l,如下:
    root@ubuntu:/home/disk1/CPP_2/TestThread# g++ -o main_11 main_11.cpp -std=c++11 -pthread 
    root@ubuntu:/home/disk1/CPP_2/TestThread# ./main_11
7、那么问题来了,-lpthread和-pthread到底什么区别?
    使用 g++ -v 输出详细信息,进行比较,发现存在一些区别。
    -pthread多了一些 -pthread, -D_REENTRANT
CPP遍历的方法汇总
1、示例代码如下:
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// C语言的惯用方法
void traversal_1(vector<int>& intVec)
{
    for (int i = 0; i < intVec.size(); i++)
    {
        printf("%d, ",intVec[i]);
    }
    printf("\n");
}

// for循环使用迭代器
void traversal_2(vector<int>& intVec)
{
    for (vector<int>::iterator iter = intVec.begin(); iter != intVec.end(); ++iter)
    {
        printf("%d, ", *iter);
    }
    printf("\n");
}

// 迭代器使用auto
void traversal_3(vector<int>& intVec)
{
    for (auto iter = intVec.begin(); iter != intVec.end(); ++iter)
    {
        printf("%d, ", *iter);
    }
    printf("\n");
}
CPP遍历的方法汇总

// foreach加lambda
// 特别注意: 这里的cbegin 返回const迭代器
void traversal_4(vector<int>& intVec)
{

    for_each(intVec.cbegin(), intVec.cend(), [](const int& val)-> void {cout <<val<<", "; });
    printf("\n");
}

// for区间遍历
// 注意: 这种方法是 traversal_3的缩写, auto val = *iter
// 需要注意这里的 auto val, val是迭代器元素的副本, 如果for(auto& val : intVec) 这样的话, 就是迭代器元素的引用
// 也就是说,auto可以理解为文本替换,但是只能替换成类型, 如果要表达const, 引用等有关的语义,必须加上相应的修饰词
void traversal_5(vector<int>& intVec)
{
    for(auto val : intVec)
    {
        printf("%d, ", val);
    }

    printf("\n");
}



int main()
{
    vector<int> intVec = { 0, 1, 2, 3, 4, 5 };

    traversal_1(intVec);
    traversal_2(intVec);
    traversal_3(intVec);
    traversal_4(intVec);
    traversal_5(intVec);

    return 0;
}
move操作
1、解决什么问题?
    考虑下面的场景,甲乙住宾馆,甲对房间里面的家具不满意,对乙房间的家具满意,而乙因为其他原因退房。
2、怎么解决这个问题?
    笨的办法是,先清空甲房间的家具,对乙房间的每个家具复制一个,搬过来。
    这就是copy赋值的做法。
3、上面的办法,显然成本比较大。更好的办法是:
    把乙房间的钥匙给甲,不就OK了嘛,反正乙不再使用房间。
4、怎么实现?
    相对于上面的copy赋值,需要增加一种copy赋值,暂且叫做move转移赋值。
    为了区分正常的copy赋值,需要区分构造参数,也就是乙不再使用房间,也就是右值,期望接收右值参数。
    而move方法就是把左值参数,转化为右值参数。
5、注意:
    move只是把参数的属性修改一下,使它成为右值,触发调用接收右值参数的copy赋值,在copy赋值中,实现对钥匙的转移。
    copy构造也是相同的道理。
6、也就是说,增加了移动构造和移动赋值。
Copyright (c) 2015~2016, Andy Niu @All rights reserved. By Andy Niu Edit.