C++ Day6 类与对象 上
- c++面向对象三大特性:封装、继承、多态。
一、封装
1.1概念
- 将属性和行为封装为一个整体
- 并加以权限控制
语法:
class 类名{
访问权限:属性、行为
};
#include<iostream>
using namespace std;
const float pi=3.14;
class circle//类
{
public://访问权限
int c_r;//属性
double getzc() //行为获取周长函数
{
return 2*pi*c_r;
}
void setcr(int r)
{
c_r=r;
}
};//封装
int main()
{
circle c;//实例化一个对象
c.c_r=2;//赋值
cout<<"圆的周长"<<c.getzc()<<endl;
c.setcr(5);
cout<<"圆的周长"<<c.getzc()<<endl;
system("pause");
}
- 属性和行为统称为成员。
- 属性:成员属性和成员变量。
- 行为:成员函数和成员方法。
1.2访问权限
- public 公共权限 :类内可以访问,类外可以访问。
- protected 保护权限:类内可以访问,类外不可以访问。继承中子类也可访问父类的保护权限。
- private 私有权限:类内可以访问,类外不可以访问。继承中子类不可访问父类的私有权限。
1.3 class和struct
访问权限不同:
- struct 默认权限:公共权限。
class 默认权限:私有
。
二、对象特性
2.1对象的初始化(构造函数)和清理(析构函数)
- 构造函数和析构函数被编译器自动调用,完成对象的初始化和清理工作。
- 编译器提供的构造函数和析构函数是空实现。
- 构造函数:用于创建对象时给对象的成员属性赋值,编译器自动调用,无需手动调用
- 析构函数:在对象被销毁前系统自动调用,执行一些清理工作。
构造函数:类名(){ }
- 没有返回值,不写void
- 函数名称与类名称相同
可以有参数,发生重载
- 程序调用对象时会自动调用构造,只会调用一次并且不用手动调用。
析构函数:~类名(){ }
- 没有返回值,不写void
- 函数名称与类名称相同,
在名称前面在~
不可以有参数,不发生重载
- 程序调用对象时会自动调用构造,只会调用一次并且不用手动调用。
#include<iostream>
using namespace std;
class student
{
public:
student()//构造函数
{
cout<<"构造函数"<<endl;
}
~student()
{
cout<<"析构函数"<<endl;
}
};
int main()
{
student c;
system("pause");
}
2.2 构造函数的分类和调用
分类方式:
- 按参数分为:有参构造和无参构造(默认)
- 按类型分为: 普通构造和拷贝构造
- 值传递给函数参数传值/值方式返回局部对象:拷贝构造。
调用方式:
- 括号调用:student s;
- 显示调用:
student s1=student(10); //调用有参
student s2=student(s1) //拷贝构造
student(10)匿名对象:当前行执行后会被回收
student(s1);非法!编译器认为:student(s1)====student s1; - 隐式转换调用:sudent s3=10;//调用有参构造
-调用默认构造函数不要用括号
,student s();加了括号(无内容)会被认为是函数声明,而不是在创建对象。
student(const student &s)//拷贝构造
{
name=s.name;
}
2.3构造函数的调用规则
c++编译器默认给一类添加三个函数:
- 默认构造函数(无参函数体为空)
- 默认析构函数(无参函数体为空)
- 默认拷贝构造函数
规则:
- 用户定义有参构造,则系统不再提供默认无参,但提供默认拷贝构造
- 用户定义拷贝构造,c++不提供其他构造函数。
写了有参构造编译器不提供默认构造
2.4 深拷贝和浅拷贝
- 浅拷贝:简单的赋值拷贝,利用编译器提供拷贝构造函数会做浅拷贝操作,问题:重复释放堆区内存引起报错,利用深拷贝解决
- 深拷贝:在堆区重新申请空间,进行拷贝操作
- 析构函数:释放堆区内存
有属性在堆区开辟,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题
student(const student &s)
{
//mage=s.age; 编译器默认操作浅拷贝
mage =new int(*s.mage);//深拷贝
}
2.5 初始化列表
- 构造函数():属性1(值1),属性2(值2)…{}
2.6 类对象作为类成员
- 类引用其他类对象时,构造时先构造其他类再构造自身
- 析构顺序相反。
2.7静态成员函数
- 所有对象共享一个函数
- 静态成员函数只能访问静态变量(大家共享一份 ),不可访问非静态成员变量,无法区分是那一个具体对象的属性。
- 静态的成员变量和静态/非静态的成员函数不属于类对象上。
只有非静态的成员变量属于类的对象上
; - 成员变量和成员函数分开存储;空对象占用
一个1个字节
静态的成员变量和静态/非静态的成员函数不占类的大小
2.7 this指针
- 解决名称冲突;
int age;
student(int age)
{
this->age=age;//谁调用this指向谁
}
- 返回对象本身 *this