Include 《A Tool of C++》、《C++ programming language》
new
new(动态存储分配),C++的一种创建对象的方式
1 2
| int a=new int{7}; int b=new int[10]
|
引用
引用与指针类似,但语法规则有很多不同
1 2 3 4 5
| int a1=2; int a2=3 int & r1=a1; int & r2=a2; r1=r2;
|
在赋值语句r1=r2
中,引用会提取r2引用的值,改变r1引用的值,而指针只会改变指针的地址,不会改变元素。
用{}赋值
使用赋值=有时会出现类型转换导致信息丢失,例如:
而使用{}能发现这一错误
函数的返回值也可以是一类对象{}:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| struct Entry{ string name; int value; };
Entry read_entry(istream& is){ string s; int i; is>>s>>i; return {s,i}; }
auto e = read_entry(cin);
cout<<"{"<<e.name<<","<<e.value<<"}\n";
|
在这个例子中,auto自动判断返回值为{s,i};
结构化绑定
续上条的代码:
1 2
| auto [n,v] = read_entry(is); cout<<"{"<<n<<","<<v<<"\n";
|
n,v
的类型是从函数read_entry
中推出的,这种给类设定局部名字的方式称为结构化绑定,例:
1 2 3 4
| map<string,int>m;
for(const auto [key,value]:m) cout<<"{"<<key<<","<<value<<"\n";
|
类
class建议先阅读private的变量名,在阅读public的构造函数(构造函数用{}赋值)
具体类型
简易复数类的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| class complex{ double re im; public: complex(double r,double i):re{r},im{i}{} complex(double r):re{r},im{0}{} conplex():re{0},im{0}{}
double real()const{return re;} void real(double d){re=d;} double imag()const{return im;} void imag(double d){im=d;}
complex & operator+=(complex z){ re+=z.re; im+=z.im; return *this; }
complex & operator-=(complex z){ re-=z.re; im-=z.im; return *this; }
complex & operator*=(complex); complex & operator/=(complex);
complex operator+(complex a,complex b){return a+=b;} complex operator-(complex a,complex b){return a-=b;} complex operator-(complex a){return {-a.real(),-a.imag()};} complex operator*(complex a,complex b){return a*=b;} complex operator/(complex a,complex b){return a/=b;}
bool operator==(complex a,complex b){ return a.real()==b.real()&&a.imag()==b.imag(); } bool operator!=(complex a,complex b){ return !(a==b); }
complex sqrt(complex); }
|
拷贝相当废内存和时间,所以经常用返回值和operator
来替代拷贝
构造+析构 函数
以vector为例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class vector{ public: vector(int s):elem{new double[s]},sz{s}{ for(int i=0;i!=s;++i) elem[i]=0; }
vector(){delete[] elem;}
double&operator[](int i); int size()const; private: double* elem; int sz; };
|
构造函数+析构函数可以让使用者无需设计释放函数,避免内存泄漏
初始化方法
C++主要是两种:初始值列表构造函数、push_back();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Vector{ public: Vector(std::initializer_list<double>); void push_back(couble); };
Vector read(istream& is){ Vector v; for(double d ;is>>d;) v.push_back(d); return v; }
Vector v=read(cin);
Vector::Vector(std::initializer_list<double>lst):elem{new double[lst.size()]},sz{static_cast<int>(lst.size())} { copy(lst.begin(),lst.end(),elem); }
|
抽象类(继承、多态)
C++的继承通过包含纯虚函数的抽象类
(基类/base)与所派生的子类/subcalss
(或超类/superclass)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Container{ public: virtual double& operator[](int)=0; virtual int size() const=0; virtual ~Container(){} }
Container c; Container* p=new Vector_container(10)
void use(Container& c){ const int sz=c.size(); }
|