程序设计与算法(三)第十周 c++新特性和c++高级主题 (1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/abc15766228491/article/details/82952263

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
using namespace std;
class A{};
A operator+(int n, const A& a)
{
    return a;
}
template<class T1, class T2>
auto add(T1 x, T2 y)-> decltype(x+y){
    return x+y;
};
int main()
{
    auto d = add(100, 1.5);// d是double d = 101.5
    auto k = add(100, A());// d是A类型
    cout<<d;
}

在这里插入图片描述
在这里插入图片描述

#include <memory>
#include <iostream>
using namespace std;
struct A{
    int n;
    A(int v=0):n(v){}
    ~A(){cout<<n<<" destructor"<<endl;}
};
int main()
{
    shared_ptr<A> sp1(new A(2));
    shared_ptr<A> sp2(sp1);
    // 上面是sp1和sp2共同托管A(2)
    cout<<"1)"<<sp1->n<<","<<sp2->n<<endl;
    shared_ptr<A> sp3;
    A*p = sp1.get();//p指向A(2)
    cout<<"2)"<<p->n<<endl;
    sp3=sp1;//sp3也托管了A(2)
    cout<<"3)"<<(*sp3).n<<endl;
    sp1.reset();
    if(!sp1) cout<<"4) sp1 is null"<<endl;
    A *q=new A(3);
    sp1.reset(q);//sp1托管q
    cout<<"5)"<<sp1->n<<endl;
    shared_ptr<A>sp4(sp1);
    shared_ptr<A>sp5;
    // sp5.reset(q)不妥,会报错
    sp1.reset();
    cout<<"before end main"<<endl;
    sp4.reset();
    cout<<"end main"<<endl;
    return 0;
}
1)2,2
2)2
3)2
4) sp1 is null
5)3
before end main
3 destructor
end main
2 destructor

在这里插入图片描述
在这里插入图片描述

// 基于范围的for循环
#include <iostream>
#include <vector>
using namespace std;
struct A{
    int n;
    A(int i):n(i){}
};
int main()
{
    int ary[]={1,2,3,4,5};
    for(int &e:ary)
        e*=10;
    for(int e:ary)
        cout<<e<<",";
    cout<<endl;
    vector<A> st(ary, ary+5);
    for(auto &it:st)
        it.n*=10;
    for(A it:st)
        cout<<it.n<<",";
    return 0;
}

在这里插入图片描述

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class String{
public:
    char *str;
    String():str(new char[1]){str[0]=0;}
    String(const char *s){
        cout<<"constructor called"<<endl;
        str = new char[strlen(s)+1];
        strcpy(str, s);
    }
    // 复制构造函数
    String(const String &s){
        cout<<"copy constructor called"<<endl;
        str = new char[strlen(s.str)+1];
        strcpy(str, s.str);
    }
    String & operator=(const String&s){
        cout<<"copy operator = called"<<endl;
        if(str!=s.str){
            delete[] str;
            str=new char[strlen(s.str)+1];
            strcpy(str, s.str);
        }
        return *this;
    }
    // 移动构造函数
    String(String &&s):str(s.str){
        // 直接指向参数s.str指向的地方,然后把原来的改变就可以了
        // 没有进行深拷贝
        cout<<"move constructor called"<<endl;
        s.str = new char[1];
        s.str[0] = 0;
    }
    String & operator=(String &&s){
        cout<<"move operator= called"<<endl;
        if(str!=s.str){
            delete[] str;
            str = s.str;
            s.str = new char[1];
            s.str[0] = 0;
        }
        return *this;
    }
    ~String(){delete[] str;}
};
template <class T>
void MoveSwap(T& a, T& b)
{

    T tmp(move(a));// std::move(a)为右值,这里调用move constructor
    a = move(b);// move(b) 为右值,因此这里会调用move assigment
    b = move(tmp);// move(tmp) 为右值,因此这里会调用move assigment
}
int main()
{
    //这里注意a,b的值会被修改,但是会避免深拷贝
    // String &r = String("string");//error,对象是一个右值,这里写成了左值
    String s;
    s = String("ok");// String("ok")是右值,调用参数为右值的赋值重载运算符
    cout<<"****"<<endl;
    String &&r = String("this");
    cout<<r.str<<endl;
    String a("hello"), b("world");
    MoveSwap(a, b);
    cout<<a.str<<endl;
    return 0;
}

constructor called
move operator= called
****
constructor called
this
constructor called
constructor called
move constructor called
move operator= called
move operator= called
world

猜你喜欢

转载自blog.csdn.net/abc15766228491/article/details/82952263