c++备忘3

    xiaoxiao2021-03-26  23

    1. new后的内存需要释放,经常被人遗忘。有人想到可以利用对象,因为对象生命周期结束后,析构函数将会被调用,可以释放它指向的内存。

    而对象的生命周期是程序自动控制的,因此可以轻松防止内存泄漏。

     

    2. 智能指针的析构函数总是释放其指向的堆内存,因此,如果不是动态创建的堆内存,将会发生内存释放错误。

     

    3. 两个指针指向同一块内存,容易发生double free的问题,如何防止?

    a 定义赋值运算符,进行深度拷贝

    b 建立所有权的转移,例如auto_ptr , unique_ptr(更严谨)

    c 创建智能更高的指针,引用计数,赋值时,计数+1,指针过期时,计数-1,仅当最后一个指针过期时才调用delete,这是shared_ptr的概念。

     

    4. auto_ptr<string> p1(new string("auto"));

    auto_ptr<string> p2;

    p2=p1;

    p2接管了p1,这是好事,因为避免double free,但是如果后面访问p1将出错。

    如果使用unique_ptr将在编译时出错,如下

    unique_ptr<string> p1(new string("auto"));

    unique_ptr<string> p2;

    p2=p1;

    但是,编译器允许将一个临时对象赋给unique_ptr,如下

    unique_ptr<string> p3=unique_ptr<string>(new string("unique"));

    此外,move() 能将一个unique赋值给另一个,实现所有权转移。如下

    unique_ptr<string> p1,p2;

    p1=unique_ptr<string>(new string("unique"));

    p2=p1;

     

    5. unique_ptr<double[]> p1(new double(5));

    auto_ptr和shared_ptr只能用new,而unique_ptr可以用new[]

     

    6. 在unique_ptr为右值时,unique_ptr 可以赋值给shared_ptr

    unique_ptr<string> pup(generateU());  ---ok

    shared_ptr<string> s1(pup);                 ----fail, unique_ptr is lvalue

    shared_ptr<string> s2(generateU());------ok,,   unique_ptr is rvalue

     

    7. c++提供了sstream族,读取string对象中的格式化信息,或将格式化信息写入string对象中---内核格式化。

    ostringstream outstr;

    string s1("OO");

    outstr<<"file format is"<<s1<<"t";

    string out = outstr.str();//返回一个被初始化为缓冲区内容的字符串对象。

    cout<<out.

     

     

    string lit = "there is a test file bellow"

    istringstream instr(lit);

    string word;

    while(instr>>word)

    {

    cout<<word<<endl;

    }

     

    8. c++11特性

    a)  新类型: long long, unsigned long long, char16_t, char32_t

    b) 初始化列表 int x{5};  short quar[3]{1,2,3};

    c) 缩窄,初始化列表语法防止缩窄。

    char c1=1.57e27-----allow, but undefined behavior

    char c1{1.57e27}-----compile error

    char c1{66}----allow

    d)

    auto 申明变量类型

    e)

    decltype变量类型声明为表达式

    decltype(x*n) q; q为x*n的类型

    f)

    返回类型后置

    auto f2(double, int)->double;

    g)

    nullptr

    h)

    作用域内枚举

    enum class New1{aa, bb, cc};

    enum struct New2{aa, bb, cc};

    调用时,New1::aa, New2::aa

    i)

    禁止自动转换

    class Pe

    {

    int mem1 = 0;--------类内成员初始化

    Pe(int);

    explicit Pe(double);

    explicit operator double() const;

    };

    Pe a, b;

    b=0.5;----------fail, 禁止单参数构造函数导致自动转换。

    double x = b;----fail, 禁止自动转换。

    double x = double(b);---ok

    j)

    Useless::Useless(const Useless &f):n(f.n)--------拷贝构造函数

    {

    f的成员赋值给当前对象的成员

    }

    Useless:Useless(Useless &&f):n(f.n) -----------转移构造函数

    {

    f的内容复制给当前对象,且f成员内容置空

    }

    Useless &Useless::operator=(const Useless &f)-----赋值函数

    {

    f成员赋值给当前对象,深拷贝

    }

    Useless &Useless::operator=(Useless &&f)---转移赋值函数

    {

    return *this;

    }

     

    k)

    如果提供了移动构造函数,编译器不会自动创建默认的构造函数,复制构造函数和赋值函数,在此情况下,可以使用default关键字声明这些默认版本;

    class A{

    public:

    A(A &&);

    A()=default;

    A(const A&) = default;

    A & operator=(const A &)=default;

    如果想禁止复制对象,可禁用复制构造函数和赋值运算符

    class A

    ....

    A(const A&)=delete;

    A &operator=(const A&)=delete;

     

    l)

    一个构造函数中使用另一个构造函数---------委托构造函数。

    例如派生类构造函数可以调用基类构造函数。

    using Base::Base;

    Derived(int a, int b):ma(a),Base(b){};

     

    m)管理虚方法

    virtual void f() const override;说明您需要覆盖一个虚函数,如果声明与基类方法不匹配,编译器将会报错。如果不使用该关键字,基类同名的方法将被隐藏。

    virturl void f() const final;禁止派生类覆盖该方法

     

    n)lambda函数表达式

    auto mod3=[](int x){return x%3==0;};  ---------返回类型自动推断

    int count = std::count_if(numbers.begin(), numbers.end(), mod3);

     仅当表达式完全由一条返回语句组成时才能自动推断返回类型,否则需要显示指定

    auto mod3=[¶](int x)->int{para++; return x%3==0;};

     

    o)包装器

    double test(double){return double*2.0;}

    function<double(double)> e1=test;

    p)省略参数

    template<typename T, typename...Args>

    void show(T value, Args...args)

    {

    ...

    }

    show(x*x,'!',7,mr);

    q)thread_local将变量声明为静态存储,随线程过期而过期。

    库支持由原子操作atomic operation库和线程支持库组成

    r)pair可以存储两个类型不同值,tuple可以存储任意多个类型不同值

    s)regex库为正则表达式库

    t)允许共用体成员有构造函数和析构函数

    转载请注明原文地址: https://ju.6miu.com/read-659039.html

    最新回复(0)