一、封装
——可以达到,对外提供接口,屏蔽数据,对内开放数据
C语言中的封装:当单一变量无法完成描述需求的时候,结构体类型解决了这一问题。
C++的封装:class封装的本质,在于将数据和行为,绑定在一起通过对象来完成操作。
二、类和对象
1、类的声明
2、权限修饰符:public、private(set/get)、protected
3、面向对象编程实例:栈的实现
4、析构函数
析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号~作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
作用:释放对象给属性分配的空间
特点:a.无返回值; b.不能重载 c.函数名:~类名 d.当实例的对象释放空间时被调用;
5、构造函数
类名的第一个字母是大写,类的属性用m开头
在public内写函数,在private内写类元素(参数)
1)class的get/set方法:提供相对安全的方式访问成员变量
2)定义一个对象需要初始化 :
init函数的缺点是:可能会忘记初始化
所以在C++中提出了构造函数,用构造函数替代init
作用:初始化对象的属性
特点:a.无返回值; b.函数名与类名相同 c.可以重载 d.定义一个对象会自动调用构造函数;
构造函数会自动调用
class Test
{
public:
Test()//无参的构造函数
{
m_num=0;
m_age=0;
m_name="";
}
Test(int num)//带参数的构造函数
{
m_num=num;
}
~Test()
{
}
void initTest()//初始化
{
m_num=0;
}
void setNum(int num)
{
m_num=num;
}
private:
int m_num;//类的成员变量一般在前面加m_
int m_age;
char m_name;
};
int main()
{
Test t;//定义对象,自动调用无参构造函数
Test t(5);//调用带参数的构造函数
t.initTest();//调用初始化函数
t.setNum(20);//给函数赋值
}
4)构造函数的种类?
默认的无参构造函数、无参构造函数、类型转换构造函数、默认拷贝构造函数、拷贝构造函数、移动拷贝构造函数(c++11)
(初始化列表)
——默认构造函数(无参构造函数)delete、default
定义默认构造函数有两种方式,一是定义一个无参的构造函数,二是定义所有参数都有默认值的构造函数
类里面没有任何自己定义的构造函数时,系统会默认生成;
Student();//无参构造函数
Student(int num26,grade=100);//定义所有参数都有默认值的构造函数
当类中含有不能默认初始化的成员变量时,可以禁止默认构造函数的生成
Student()=delete;//表示删除默认构造函数
Student()=default;//表示默认存在构造函数
当类中含有不能默认拷贝成员变量时,可以禁止默认构造函数的生成
myClass(const myClass&)=delete;//表示删除默认拷贝构造函数,即不能进行默认拷贝
myClass & operatir=(const myClass&)=delete;//表示删除默认拷贝构造函数,即不能进行默认拷贝
——类型转换构造函数
实例:
类型转换运算符重载:operator
class A
{
public:
explicit A(int num)//类型转换构造函数
{
m_num=num;
}
operator int()
{
return m_num;
}
int m_num;
};
int main()
{
A a1=1;//类型转换,将一个整型常量赋值给一个类型对象,也就是发生隐式转换,会有风险
//为了防止发生隐式转换,用explicit
//用explicit阻止发生类型转换,要想继续发生类型转换,需要用到类型转换重载运算符operator
A a4;
int num=static_cast<int>(a4);
return 0;
}
——有参无参的构造函数
student();//无参构造函数
student(int num,int grade,char name);//有参构造函数
——隐式转换和explicit
C++中的数据类型转换可以分为隐式转换和显示转换
1.显示转换即使用static_cast等方法进行转换
2.隐式转换则是编译器完成的,如bool和int之间的默认转换
3.实际开发中,应尽量避免使用隐式转换,代码是给人看的,而不是炫技
所以可以使用explicit来禁用构造函数的隐式转换
——构造函数初始化列表
必须用带有初始化列表的构造函数:
1.成员类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。
2.const 成员或引用类型的成员。因为 const 对象或引用类型只能初始化,不能对他们赋值。
class Student
{
public:
//构造函数初始化列表
int num;
int grade;
Student():num(26),grade(100)
{
}
//构造函数内部赋值
Student()
{
num=26;
grade=100;
}
};
——拷贝构造函数
默认的拷贝构造函数:当类中无拷贝构造函数时,系统会默认生成一个拷贝构造函数:A (const A &a);
自定义拷贝构造函数:赋值运算符重载 拷贝 VS 赋值
//自定义的拷贝函数
A (const A &other)
{
m_num=other.m_num;
}
//运算符重载
A& operator =(const A &other)
{
cout << "A operator A" << endl;
m_num = other.m_num;
}
int main()
{
//自定义的拷贝函数
A a(1);
A a1(a);
//赋值运算符
A a2;
a2=a;
}
默认/自定义的拷贝构造函数存在问题:浅拷贝和深拷贝? 作业!!!!!
——移动构造函数