C++学习总结
引用
- 定义引用时一定要将其初始化成引用某个变量
- 引用初始化后,就不改变了。
- 引用只能引用变量,不能引用常量和表达式
int n;double a;
int &r=n;
double &r1=a; //引用与引用的变量为一体
引用带来的好处,避免如C语言需要形参实参的传递,比如交换两个数的函数。
void swwap(int &a,int &b){
int temp;
temp=a;a=b;b=temp;
}
//可以直接交换a和b的值
引用作为函数的返回值
int n=4;
int &setvalue(){return n;}
int main(){
setvalue()=40;
cout<< n;//输出40
return 0;
}
常引用 const T &
注意:不能把常引用赋值给非常引用,反之则可以。
内联函数inline
为了减少函数调用的开销,引入了内联函数的机制。编译器处理内联函数的调用语句时,是将整个函数的代码插入到调用语句处,而不会产生调用函数的语句。
inline int Max(int a, int b){
if(a>b) return a;
return b;
}
new与delete
const int N=100;
p=new T; //T是变量的类型
delete p;
p=new T[N];
delete []p; //指针必须指向new出来的数组
函数重载
定义:多个函数,名字相同,而参数个数和参数类型不同。
类
类=成员变量+成员函数,和结构变量一样,对象所占用的内存空间的大小,等于所有成员变量的大小之和,对象之间可以用**=**进行赋值
定义一个类:
class 类名{
private:
私有属性和函数;
public:
共有属性和函数;
protected:
保护属性和函数;
};
如果某个成员面前没有上述关键字,则缺省地被认为是私有成员。用struct定义类,和class的唯一区别就是,未说明是共有还是私有的成员,就是共有。
在类的成员函数内部,能够访问:
- 当前对象的全部属性和函数
- 同类其他对象的全部属性和函数
在类的成员函数以外的地方,只能够访问该类对象的共有成员
class CEmployee{ //雇佣者的一个类
private:
char szName[30]; //名字
public:
int salary;
void setName(char *name);
void getName(char *name);
void averagesalary(CEmployee e1,CEmployee e2);
};
void CEmployee::setName(char *name){
strcpy(szName,name);
}
void CEmployee::getName(char *name){
strcpy(name,szName);
}
void CEmployee::averagesalary(CEmployee e1,CEmployee e2){
cout <<e1.szName;
salary=(e1.salary+e2.salary)/2;
}
int main(){
CEmployee e;
strcpy(e.szName,"Tom1234567889"); //不能访问私有成员,编译错
e.setname("Tom");
e.salary=5000;
return 0;
}//其余的访问正常
构造函数、复制构造函数、析构函数、类型转换构造函数
构造函数的基本概念:
- 名字与类名相同,可以有参数,不能有返回值(void也不行)
- 作用是对对象进行初始化,如给成员变量赋初值
- 如果定义时没有写构造函数,则编译器生成一个默认的无参数的构造函数;如果定义了则编译器不自动生成。
- 一个类可以有多个构造函数
构造函数的使用:
class Complex{
private:
double real,imag;
public:
void Set(double r,double i);
Complex(double r,double i);
Complex(double r);
Complex(Complex c1,Complex c2);
};
Complex::Complex(double r,double i){
real=r;imag=i;
}
Complex::Complex(double r){
real=r;imag=0;
}
Complex::Complex(Complex c1,Complex c2){
real=c1.real+c2.real;
imag=c1.imag+c2.imag;
}
Complex c1(3),c2(1,0),c3(c1,c2); //初始化
复制构造函数的基本概念:
- 只有一个参数,即对同类对象的引用
- 形如X::X(X&) 或X::X(const X&) ,二者选一,后者能以常量对象作为参数
- 如果没有定义复制构造函数,则编译器生成默认的复制构造函数,默认的复制构造函数完成复制功能。
复制构造函数起作用的情况:
-
当用一个对象去初始化同类的另一个对象时
complex c2(c1);
complex c2=c1; -
如果某函数有一个参数是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用。
class A
{
public:
A(){}; //构造函数
A(A&a){ //复制构造函数
cout<<"Copy constructor called"<<endl;
}
};
- 如果函数的返回值是类A的对象时,则A返回时,A的复制构造函数将被调用。
析构函数的基本概念:
- 名字与类名相同,在前面加’~’,没有参数和返回值,一个类最多只能有一个析构函数。
- 析构函数对象消亡时即自动被调用。可以定义析构函数来在对象消亡前做善后工作,比如释放分配的空间等。
- 如果定义时没写析构函数,则编译器自动生成缺省析构函数,缺省析构函数什么也不做。
class String{
private :
char *p;
public:
~String(); //析构函数
};
String::~String(){
delete []p;
}
类型转换构造函数的概念:
- 定义转换构造函数的目的是实现类型的自动转换
- 只有一个参数,而且不是复制构造函数的构造函数,一般就可以看作是转换构造函数
- 当需要的时候,编译系统会自动调用转换构造函数,建立一个无名的临时对象(或临时变量)
class Complex{
public::
double real,imag;
Complex(int i){ //类型转换构造函数
cout<<"InConstructor called"<<endl;
real=i;imag=0;
Complex(double r,double i){real=r;imag=i;}
};
int main(){
Complex c1(7,8);
Complex c2=12;
c1=9; //9被自动转换为一个临时Complex变量
cout<<c1.real<<","<<c1.imag<<endl;
return 0;
}