8.8日知识点总结

敲了几天的基础知识demo,发现特别容易忘记,于是决定接下来的每一天都把敲过的基础代码贴到博客上,一来是自己把知识点重新梳理,加深理解;二来是把自己对一些问题的解决办法都记录下来,以便以后备忘。

今天的知识点比较零乱,我得好好整理。
1.引用包装器

#include 
template<typename T>
void com(T arg)
{
    std::cout << &arg << std::endl;
    arg++;
}
void main()
{
    int num = 20;
    std::cout << &num << " " << num << std::endl;
    com(std::ref(num));//std::ref//会把传入的值包装成可引用的值
    com(num);
    std::cout << &num << " " << num << std::endl;
    std::cin.get();
}

2.C++智能指针
unique_ptr是一个独享所有权的智能指针,它提供了严格语义上的所有权,包括:
1,拥有它所指向的对象;
2,无法进行复制构造,也无法进行复制赋值操作。也就是说,我们无法得到指向同一个对象的两个unique_ptr。但是可以进行移动构造和移动赋值操作。
3,保存指向某个对象的指针,当它本身被删除释放的时候,会使用给定的删除器释放它所指向的对象。

c++11新出现的智能指针auto_ptr,存在于头文件memory中。
下面的代码是VS2013里面的源码:

template<class _Ty,
    class _Dx>  // = default_delete<_Ty>
    class unique_ptr
        : private _Unique_ptr_base<_Ty, _Dx,
            is_empty<_Dx>::value
                || is_same, _Dx>::value>
    {   // non-copyable pointer to an object
public:
    typedef unique_ptr<_Ty, _Dx> _Myt;
    typedef _Unique_ptr_base<_Ty, _Dx,
        is_empty<_Dx>::value
            || is_same, _Dx>::value> _Mybase;
    typedef typename _Mybase::pointer pointer;
    typedef _Ty element_type;
    typedef _Dx deleter_type;

    using _Mybase::get_deleter;

    unique_ptr() _NOEXCEPT
        : _Mybase(pointer())
        {   // default construct
        static_assert(!is_pointer<_Dx>::value,
            "unique_ptr constructed with null deleter pointer");
        }

    unique_ptr(nullptr_t) _NOEXCEPT
        : _Mybase(pointer())
        {   // null pointer construct
        static_assert(!is_pointer<_Dx>::value,
            "unique_ptr constructed with null deleter pointer");
        }

    _Myt& operator=(nullptr_t) _NOEXCEPT
        {   // assign a null pointer
        reset();
        return (*this);
        }

    explicit unique_ptr(pointer _Ptr) _NOEXCEPT
        : _Mybase(_Ptr)
        {   // construct with pointer
        static_assert(!is_pointer<_Dx>::value,
            "unique_ptr constructed with null deleter pointer");
        }

    unique_ptr(pointer _Ptr,
        typename _If::value, _Dx,
            const typename remove_reference<_Dx>::type&>::type _Dt) _NOEXCEPT
        : _Mybase(_Ptr, _Dt)
        {   // construct with pointer and (maybe const) deleter&
        }

    unique_ptr(pointer _Ptr,
        typename remove_reference<_Dx>::type&& _Dt) _NOEXCEPT
        : _Mybase(_Ptr, _STD move(_Dt))
        {   // construct by moving deleter
        static_assert(!is_reference<_Dx>::value,
            "unique_ptr constructed with reference to rvalue deleter");
        }

    unique_ptr(unique_ptr&& _Right) _NOEXCEPT
        : _Mybase(_Right.release(),
            _STD forward<_Dx>(_Right.get_deleter()))
        {   // construct by moving _Right
        }

    template<class _Ty2,
        class _Dx2,
        class = typename enable_if::value
            && is_convertible<typename unique_ptr<_Ty2, _Dx2>::pointer,
                pointer>::value
            && ((is_reference<_Dx>::value && is_same<_Dx, _Dx2>::value)
                || (!is_reference<_Dx>::value
                    && is_convertible<_Dx2, _Dx>::value)),
            void>::type>
        unique_ptr(unique_ptr<_Ty2, _Dx2>&& _Right) _NOEXCEPT
            : _Mybase(_Right.release(),
                _STD forward<_Dx2>(_Right.get_deleter()))
        {   // construct by moving _Right
        }

    template<class _Ty2,
        class = typename enable_if::value
            && is_same<_Dx, default_delete<_Ty> >::value,
            void>::type>
        unique_ptr(auto_ptr<_Ty2>&& _Right) _NOEXCEPT
            : _Mybase(_Right.release())
        {   // construct by moving _Right
        }

    template<class _Ty2,
        class _Dx2>
        typename enable_if::value
            && is_convertible<typename unique_ptr<_Ty2, _Dx2>::pointer,
                pointer>::value,
            _Myt&>::type
        operator=(unique_ptr<_Ty2, _Dx2>&& _Right) _NOEXCEPT
        {   // assign by moving _Right
        reset(_Right.release());
        this->get_deleter() = _STD forward<_Dx2>(_Right.get_deleter());
        return (*this);
        }

    _Myt& operator=(_Myt&& _Right) _NOEXCEPT
        {   // assign by moving _Right
        if (this != &_Right)
            {   // different, do the move
            reset(_Right.release());
            this->get_deleter() = _STD forward<_Dx>(_Right.get_deleter());
            }
        return (*this);
        }

    void swap(_Myt& _Right) _NOEXCEPT
        {   // swap elements
        _Swap_adl(this->_Myptr, _Right._Myptr);
        _Swap_adl(this->get_deleter(),
            _Right.get_deleter());
        }

    ~unique_ptr() _NOEXCEPT
        {   // destroy the object
        if (this->_Myptr != pointer())
            this->get_deleter()(this->_Myptr);
        }

    typename add_reference<_Ty>::type operator*() const
        {   // return reference to object
        return (*this->_Myptr);
        }

    pointer operator->() const _NOEXCEPT
        {   // return pointer to class object
        return (_STD pointer_traits::pointer_to(**this));
        }

    pointer get() const _NOEXCEPT
        {   // return pointer to object
        return (this->_Myptr);
        }

    explicit operator bool() const _NOEXCEPT
        {   // test for non-null pointer
        return (this->_Myptr != pointer());
        }

    pointer release() _NOEXCEPT
        {   // yield ownership of pointer
        pointer _Ans = this->_Myptr;
        this->_Myptr = pointer();
        return (_Ans);
        }

    void reset(pointer _Ptr = pointer()) _NOEXCEPT
        {   // establish new pointer
        pointer _Old = this->_Myptr;
        this->_Myptr = _Ptr;
        if (_Old != pointer())
            this->get_deleter()(_Old);
        }

    unique_ptr(const _Myt&) = delete;
    _Myt& operator=(const _Myt&) = delete;
    };

下面简陋对比一下auto_ptr和unique_ptr的区别:

double *p = new double;//为指针分配内存
        std::auto_ptr<double> autop(p);
std::unique_ptr pdb(new double);

3.调试以及静态断言
在使用前需包含assert.h头文件

static_assert(sizeof(num) >= 4, "yincheng error");//静态断言
//各种宏可以更好地调试代码,迅速锁定代码错误在哪一行
cout << __FILE__ << endl;
cout << __LINE__ << endl;
cout << __DATE__ << endl;
cout << __TIME__ << endl;
cout << __FUNCTION__ << endl;

4.c++别名

typedef  int(*ADD)(int a, int b);
using  FUNC = int (*)(int a, int b);//别名
using  co = std::ios_base::fmtflags;//using只可以用于简写数据类型

5.c++多线程
要使用C++多线程,需包含thread.h头文件,同时
using namespace std::this_thread;

// thread::hardware_concurrency线程
    auto n = thread::hardware_concurrency();
    std::cout << n << std::endl;
    //获取当前线程编号
    std::cout << "thread=" << get_id() << std::endl;


   thread thread1(msg);//创建多线程
   thread thread2(msg);
   thread1.join();//开始执行
   thread2.join();

这样即可实现并发执行。

6.模板元编程
/主要思想
//
//利用模板特化机制实现编译期条件选择结构,利用递归模板实现编译期循环结构,模板元程序则由编译器在编译期解释执行。
//
//优劣及适用情况
//
//通过将计算从运行期转移至编译期,在结果程序启动之前做尽可能多的工作,最终获得速度更快的程序。也就是说模板元编程的优势在于:
//
//1.以编译耗时为代价换来卓越的运行期性能(一般用于为性能要求严格的数值计算换取更高的性能)。通常来说,一个有意义的程序的运行次数(或服役时间)总是远远超过编译次数(或编译时间)。
//
//2.提供编译期类型计算,通常这才是模板元编程大放异彩的地方。
//
//模板元编程技术并非都是优点:
//
//1.代码可读性差,以类模板的方式描述算法也许有点抽象。
//
//2.调试困难,元程序执行于编译期,没有用于单步跟踪元程序执行的调试器(用于设置断点、察看数据等)。程序员可做的只能是等待编译过程失败,然后人工破译编译器倾泻到屏幕上的错误信息。
//
//3.编译时间长,通常带有模板元程序的程序生成的代码尺寸要比普通程序的大,
//
//4.可移植性较差,对于模板元编程使用的高级模板特性,不同的编译器的支持度不同。

//模板元吧运行时消耗的时间,在编译期间优化
//模板元编程递归实现斐波那契数列计算,大大提高运行速度
template<int N>
struct data
{
    enum a{ res = data1>::a::res + data2>::a::res
 };
};
template<>
struct data<1>
{
    enum a{res =1};
};

template<>
struct data<2>
{
    enum a{res= 1 };
};
//普通函数递归实现
int getdata(int n)
{
    if (n==1 || n==2)
    {
        return 1;
    } 
    else 
    {
        return getdata(n - 1) + getdata(n - 2);
    }
}
void main()
{
    const int myint = 40;
    int num = data::res;//<>内部不可以有变量
    std::cout << num << std::endl;

    std::cout << getdata(40) << std::endl;


    std::cin.get();
}

7.内部函数绑定

#include
#include//处理函数
using namespace std;
using namespace std::placeholders;
//仿函数,创建一个函数指针,引用一个结构体内部或者一个类内部的公有函数
struct MyStruct
{
    void add(int a)
    {
        cout << a << endl;
    }

    void add2(int a,int b)
    {
        cout << a +b<< endl;
    }
    void add3(int a, int b,int c)
    {
        cout << a + b +c<< endl;
    }
};
void main()
{
    MyStruct struct1;
    //创建函数指针,类结构体,数据私有,代码共享
    //函数通过调用,调用需要传递对象名进行区分
    void(MyStruct::*p)(int a) = &MyStruct::add;
}
int main1()
{
    MyStruct struct1;
    //auto自动变量,地址,函数指针,bind绑定
    //第一个参数引用内部函数,绑定一个实体对象,
    auto func = bind(&MyStruct::add, &struct1, _1);
    auto func2 = bind(&MyStruct::add2, &struct1,_1, _2);
    auto func3 = bind(&MyStruct::add3, &struct1, _1, _2,_3);
    func(100);
    func2(10, 20);
    func3(10, 20,30);
    cin.get();
    return 0;
}

你可能感兴趣的:(c++基础)