程式設計與演算法(三)第十週 c++新特性和c++高階主題 (1)
阿新 • • 發佈:2019-01-10
#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