目录
1.面向过程与面向对象
C语言是面向过程的语言,关注的是解决问题的过程与方法。 C++可以说是C语言的延伸与发展,不仅继承了C的一些优势,而且还多了一样非常重要的东西——面向对象。
那面向过程和面向对象有什么区别呢?
我们知道,外卖产业需要四方的支持才能产生:顾客、商家、骑手、平台。
面向过程就类似研究如何实现这一过程的每个步骤的运转成立。 先让顾客下单,平台处理向骑手发布任务,骑手接单到商家取餐,最后送至顾客。它考虑的是每一个过程的如何实现。
面向对象是分模块来完成,顾客、平台、商家、骑手四个模块,分别干什么,让他们各自处理各自的事情,是以对象为基准来实现运转。
如果从程序的实现角度来说,C语言这种面向过程的就必须要将每一方的行动做成函数,逐一实现
面向过程则可以将每一方封装起来,不管是他的信息还是行为,都可以全部装到一起,没必要一个动作一个动作写成函数再调用,可以全部放到一个类下面。
意思就是,C++的结构下,可以将信息(如:人的年龄、性别等变量)和动作(函数)放到一个类下,这是C语言做不到的。
举个例子。
(c语言实现)
struct stu
{
char name[20];
int age;
char ID[19];
//...
};
struct teacher
{
int name;
int age;
char ID[19];
//...
};
void StuReturnSchool(struct stu* ps)
{
//...
}
void TeaReturnSchool(struct teacher* pt)
{
//...
}
void StuRegisterSchool(struct stu* ps)
{
//...
}
void TeaRegisterSchool(struct teacher* pt)
{
//...
}
c++实现
class stu
{
char name[20];
int age;
char ID[19];
//...
void StuReturnSchool(stu* ps)
{
}
void StuRegisterSchool(stu* ps)
{
}
};
class teacher
{
int name;
int age;
char ID[19];
//...
void TeaReturnSchool(teacher* pt)
{
}
void TeaRegisterSchool(teacher* pt)
{
}
};
因此,面向对象的优势此时就被体现出来了。
我们可以将老师作为一个整体封装到一个类下面。里面不仅存老师的信息,也存老师的登录、报到等一系列动作的函数接口。这样就方便很多了,而且看上去也是一目了然。
2.类的定义
class className
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
2.类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::
在实际应用中尽量用第二种
3.类的访问限定符及封装
1>.访问限定符
protected(保护):类外不可以访问,自己的成员函数内可以访问。
private(私有):和保护相似,具体区别会在后面展开。
注意:访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
在C++中struct和class的区别: class的默认访问权限为private,而struct的默认访问权限为public(因为在C++中struct要兼容C)
2>类的作用域
class STU
{
public:
void Show();//成员函数
private:
//成员变量
char _name[10];//学生姓名
int _math;//学生数学成绩
int _chinese;//学生语文成绩
};
//这里需要指定Show函数是属于STU这个类域
void STU::Show()//成员函数
{
cout << "姓名:" << _name << " 数学:" << _math << " 语文:" << _chinese << endl;
}
3>.c++的一些约定
int_year;
int_day;
4>.封装
面向对象有三大特性:封装、继承、多态。这三个是最主要的。
我们现在所学的类就是封装的一大体现。其本质就是把一系列相关的东西都封到一个地方。
类里面有公有和私有,想给外面使用的就设为公有(如成员函数,不想给外面使用的就设为私有(如成员变量)。
以数据结构的栈为例,C语言实现的时候相对自由一些,它的数据和方法(变量和函数)不是在一起的,是分离的。 而C++则是将数据和方法都封装在了一个类下。
5>.类的大小
空类
结论:一个类的大小,实际就是该类中”成员变量”之和,当然要注意内存对齐
不论是类里面只有函数没有变量,还是什么都没有,编译器默认给的大小是1,不是0
也就是说编译器会给1个字节占位,它不存储有效数据,仅标识类存在。
1. 第一个成员在与结构体偏移量为0的地址处。2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为83. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
6>.类对象的存储方式
为什么成员变量在对象中,成员函数不在对象中呢?
每个对象成员变量时不一样的,需要独立存储
每个对象调用成员函数是一样的.放到共享公共区域(代码段)..
4.this指针
class Date
{
public:
void Init(int year = 1,int month = 1,int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << " " << _month << " " << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2;
d1.Init(2022,1,1);
d2.Init(2022,1,2);
d1.Print();
d2.Print();
return 0;
}
1.this指针特点
2.this指针的面试题
1.. this指针存在哪里?
栈里面,因为他是隐含形参
2.看下面两个代码的区别
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:
void Print()
{
cout << "Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
return 0;
}
这个答案是C,正常运行,为什么呢
上面已经说了,成员变量在对象中,成员函数在公共代码段
这里先看函数在不在对象里面,不在的话要去公共代码段里面
p是空指针不假,但是注意:print函数的地址是在公共代码区的(代码段),而非在对象里,编译器去找print函数不会去对象里找,而是直接去代码段,所以这里p->Print()不发生解引用。p是A的指针,直接传给print函数的this指针,指针可以为空,不会报错,因此正常运行,第一题选C。
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->PrintA();
return 0;
}
这个B运行崩溃
为什么呢?
_a是成员变量,在对象里面去找,this指针会解引用,空指针解引用会报错
cout << this->_a << endl;
->不一定是解引用,解引用是看他是否在对象里面去找
文章参考了一些大佬的资料,谢谢观看