本文是对"铁道版"c++一书的知识点总结,如果侵权,请及时告知我,将尽快删去,本文禁止转载
类的构成
不能在类声明中给数据成员赋初值
成员函数的定义
::set()或set()是普通的函数
在类的声明中,成员函数原型的参数表可以不说明参数的名字,而只说明它们的类型
void set(int , int );
内联成员函数的定义
- 隐式声明:将成员函数直接定义在类的内部
- 显示声明:在类内函数原型声明前或在类外定义成员函数前冠以关键字inline
必须将类的声明和内联成员函数的定义都放在同一个文件(或同一个头文件)中
对象的定义和使用
在声明类的同时,直接定义了对象
Class {
…
}op1,op2;
声明了类之后,在使用时再定义对象
对象中成员的访问
- 在类的内部所有成员之间都可以通过成员函数直接访问,但是在类的外部不能访问对象的私有成员
- 在定义对象时,若定义的是指向此对象的指针变量,则访问此对象的成员时,不能用“.”操作符,而应该使用“->"操作符
对象赋值语句
当类中存在指针时,使用默认的赋值运算符函数进行对象赋值,可能产生错误
构造函数和析构函数
类名 对象名[(实参表)];
类名 *指针变量名=new 类名[(实参表)]
pscore=new Score(80,88);
- 构造函数的名字必须与类名相同
- 构造函数没有返回值
- 构造函数的函数体可写在类体内。也可写在类体外
- 构造函数一般声明为公有成员
- 构造函数可以不带参数
成员初始化列表
在c++中某些类型的成员是不允许在构造函数中用赋值语句直接赋值的(对于用const修饰的数据成员,或是引用类型的数据成员,是不允许赋值语句直接赋值的)
类成员是按照它们在类里被声明的顺序进行初始化的,与它们在成员初始化列表中列出的顺序无关
带有默认参数的构造函数
析构函数
- 析构函数与构造函数名字相同,但它前面必须加一个”~“
- 析构函数没有参数,没有返回值,不能重载
- 当撤销对象时,编译系统会自动调用析构函数
注意在主程序结束后析构函数的调用
- 如果定义了一个全局对象,则在程序流程离开其作用域(如main()函数结束或调用exit()函数)时调用全局对象的析构函数
- 如果一个对象被定义在一个函数体内,则当这个函数被调用结束时,该对象应该释放,析构函数被自动调用
- 若一个对象是使用new运算符动态创建的,在使用delete运算符释放它时,delete会自动调用析构函数
默认的构造函数和默认的析构函数
如果没有定义构造函数的类,其公有数据成员可以用初始值列表进行初始化
只要一个类定义了一个构造函数,系统将不再给它提供默认的构造函数
#include<iostream>
using namespace std;
class Myclass
{
public:
char name[10];
int no;
};
int main()
{
Myclass a={"chen",25};
cout << a.name << ' ' << a.no << endl;
return 0;
}
构造函数的重载
在一个类中,当无参数的构造函数和带默认参数的构造函数重载时,有可能产生二义性
拷贝构造函数
- 因为拷贝构造函数也是一种构造函数,所以其函数名与类名相同,并且函数也没有返回值
- 拷贝构造函数只有一个参数,并且是同类对象的引用
- 每个类都必须有一个拷贝构造函数
类名::类名(const 类名 &对象名)
{
…
}
调用拷贝构造函数的一般形式
类名 对象2(对象1);
类名 对象2=对象1;
默认的拷贝构造函数将对象p1的各个域的值都复制给了对象p2相应的域,因此p2对象的数据成员的值与p1对象的完全相同
调用拷贝构造函数的3种情况
当用类的一个对象去初始化该类的另一个对象时
当函数的形参是类的对象,调用函数进行形参和实参结合时
当函数的返回值时对象,函数执行完成返回调用者时
Score p2(p1);
Score p3=p1;
fun1(Score p)
{
p.disp();
}
int main()
{
Score p1(80,88);
fun1(p1);
return 0;
}
Score fun2(Score p)
{
Score p1(80,88);
return p1;
}
int main()
{
Score p2;
p2=fun2();
return 0;
}
浅拷贝和深拷贝
当调用默认的拷贝构造函数时,拷贝的对象和被拷贝的对象中的指针会指向同一地址,当被拷贝的对象被撤销后,拷贝的对象指针所指内存区域已被释放,且当撤销拷贝的对象时,企图释放同一内存,从而导致了对同一内存空间的两次释放,这也是不允许
这就需要自己定义拷贝构造函数,为指针独立的分配一个空间,并将被拷贝对象指针所指的内容拷贝到那段空间中