一:c++面向对象
c++和c的区别
c面向过程,关注过程
c++面向对象,关注对象
比如
c语言关注洗衣服的过程
c++更关注洗衣服的对象:小女孩,衣服,木盆等
但由于c++兼容c,所以c++同时面向对象和过程
面向对象的特点:
面向对象的特点:
面向对象的三大特性:封装、继承、多态。
类的一大特性便是封装
封装是一种更好的严格管理
不封装是一种自由管理
在类外无法访问private内的成员,访问publuc中的成员也需要指明类访问
二:类
c++面向对象的特点的体现在类上
C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型
一:类的引入
1.c++兼容c的结构体
1.c++兼容c的结构体,同时将其升级成了类,可以直接使用类名
struct Student
{
char* _name;
int _age;
int _id;
}
2.c++中:“结构体”的不同
c++的类和c的结构体不一样的地方,除了可以定义变量,还可以定方法和函数
class Student
{
char* _name;
int _age;
int _id;
void Init(char* name,int age,int id)
{_name=name;
_age=age;
_id=id;
}
void Print()
{
cout<<_name<<endl;
cout<<_age<<' ';
cout << _id;
}
}
(这就在结构体中加入了函数(也叫方法))
原因
c++把c中的结构体升级为了类
二.类的定义
类的关键词有两个:struct和class
class className//或struct structName
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
三.类的组成
访问限定符
(1).public
public修饰的成员在类外可以随意访问
(2).private
private修饰的成员在类外不可以随意访问
struct默认的访问限定是public,class默认的访问限定是private
注意:不建议使用类名的默认访问限定,建议全部写清楚(如下)
class Date
{
private:
int _year;
int _month;
int _day;
public:
void Init(int year,int month,int day)
{_day=day;
_year=year;
_month=month;
}
void Print()
{
cout<<_year<<'-'<<_month<<'-'<<_day<<endl;
}
};
成员
每个对象都有独立的成员变量,但成员函数会调用同一个(如下)
注意:函数在类中有可能被编译器搞成内联函数
(不知道内联函数建议看我上一篇博客http://t.csdn.cn/OQgk8)
(1).成员大小
计算类或类对象大小,只看成员变量,考虑内存对齐,规则与c一样
空类会给一字节,不存储数据。只是站位,用来表示其存在
怎么计算:
1. 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的对齐数为8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
四:类中函数隐藏的this指针
class Date
{
private:
int _year;
int _month;
int _day;
public:
void Init(int year,int month,int day)
{_day=day;
_year=year;
_month=month;}
void Print()
{ cout<<_year<<'-'<<_month<<'-'<<_day<<endl;}//_year==this->_year
};
int main() {
Date d1;
d1.Init(2022,1,1);
d1.Print();//==Print(Date*this)
}
(1). d1.Print()隐含的this指针 ==Print(Date*this)
(2).Print函数中的_year==this->_year(_month和_day类似)
注意:调用成员函数时不可以在使用和定义(实参和形参)时添加Data* const this,(如Print(Date*const this))编译器自动添加,在类中展开用this->_year可以,但this不能别修改
(知识回顾:在*前加const,不能改变指针指向的内容,在*之后不能改变指针本身)
(3).this一般存在栈里面,作为形参 也有可能把其放在寄存器中,提高运行效率 如vs2019放到ecx中
观察下面的代码,猜想结果
class A
{
public:
void Show1()
{ cout<<" 0 "<<endl;}
void Show2()
{cout<<_a<<endl;}
private:
int _a;
};
int main()
{A*p=nullptr
p->Show1();
p->Showw2();}
提示1:A*p=nullptr;//编译器不会检查空指针
提示2:p->Show1();//不会编译报错
(和你猜想的一不一样呢?)
原因:
(1). A*p=nullptr;//编译器不会检查空指针
(2). p->Show1();//p虽然是空指针,但不会编译报错,不是语法错误,编译器检查不出来,p虽然是成员函数但不会出现空指针访问(只是有p而不访问里面的内容),虽然成员函数没在对象中 但会把p作为实参传递给隐藏this指针
(3). p->Show2();//运行到此报错结束,因为访问了空指针