封装
c++里struct和class没什么区别,区别在于默认访问权限不同,struct默认的访问权限是public,class默认权限是private
成员属性设为私有
- 可以自己控制读写权限
- 对于写数据可以控制其有效性
写入数据时可以进行检查
构造函数
语法
类名(){}
- 构造函数没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数因此可以发生重载
- 调用对象时会自动调用构造,无需手动调用,且只会调用一次
构造函数分类
有参构造和 无参构造
普通构造函数和拷贝构造函数
拷贝构造函数
Person(const Person &p)
{
}
怎么调用
括号法
- 默认构造
person p;
- 有参构造
Person p(1);
初始化列表
foo(string s, int i):name(s), id(i){} ; // 初始化列表
- 拷贝构造
Person p1(p);
拷贝构造函数的使用时机
- 使用一个已经创建完毕的对象初始化一个新对象
- 值传递的方式给函数传递值(实参传给形参,自动调用拷贝构造函数)
void doWork(person p)
{
cout<<p.age;
}
- 值方式返回局部对象
person doWork()
{
person p;
return p;
}
显示法
Person p2 = Person(20);
Person p3 = Person(p2);
Person p4 = 10 //等价于 Person p4 = Person(10);
Person(20) 这个是一个匿名对象,这个语句执行完之后就被释放
注意事项
- 调用默认构造函数的时候不要加() 原因: 编译器会认为这是一个函数声明
- 不要利用拷贝构造函数初始化匿名对象,编译器会认为这是一个对象的声明,会报重定义错
- c++默认给一个类提供三个函数,一个默认构造函数,一个析构函数一个拷贝构造函数
- 如果写了有参构造函数就不会提供默认的无参构造函数了,如果写了拷贝构造函数也不会提供默认构造函数
- 默认拷贝构造函数实际上在做一个浅拷贝,会逐字节拷贝,带来的问题是堆区内存重复释放发生非法操作
- 所以如果有在堆区开辟的函数,一定要自己提供析构函数
析构函数
- 函数名和类名相同,在名称前加~
- 不可以有参数,不可能有重载
- 对象在销毁前会自动调用析构函数,且只会调用一次
- 没有返回值,不写void
- 通常用于把在堆区的数据释放
类函数
函数的声明写在头文件(.h)文件
在.cpp文件中写函数定义
返回值 类名::函数名()
{
}
对象成员
c++ 一个类可以作为另一个类的对象,被称为对象成员
类似于c中结构体套结构体
当其他类对象作为本类成员,先调用其他类的构造函数再调用本类的构造函数
先调用本类的析构函数再调用其他类的析构函数
静态成员
在成员前加 static
静态成员变量(相当于python里的class value)
所有对象共享一份数据
在编译阶段分配内存
类内声明,类外初始化,必须的操作
class person
{
public:
static int number;
}
int person::number = 10;
//静态成员变量可以通过类名访问
cout<<person::number<<endl;
静态成员函数
静态成员函数所有对象共享同一个函数,静态成员函数只能访问静态成员变量
c++对象和this指针
在c++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上
空对象占用内存空间是1
c++编译器把每一个空对象分配一个字节空间,区分空对象占内存的位置
不是空的就没有那一个额外字节了
this指针
this指针不需要传参可以直接用,是默认创建的指向对象本身的指针,this指针本身是一个指针常量
链式编程
return *this;
返回值写person &,返回一个引用才是返回的本体,返回值的话会创建新的对象
当形参和成员变量冲突的时候可以用this指针区分
如果使用了this指针最好对空指针做一下特殊处理
const修饰成员函数
成员函数圆括号后加const,这个函数我们称为常函数
- 常函数不可以修改成员属性(除非这个成员属性声明时加了mutable关键字),大概相当于给this指针加了一个const,变成了 const classname *const this
常对象
声明对象前加const称该对象为常对象
常对象只能调用常函数
常对象不可以修改成员属性(除非这个成员属性声明时加了mutable关键字)