目录
5.4、立方体类案例中,用成员函数判断两个立方体是否相等编辑
1、栈区
栈区里存放的数据是:局部变量、形参等,空间是由编译器自行创建和释放的。
因此注意不要返回一个局部变量的地址来使用,因为这个地址不知道编译器何时会被开辟它用、或何时会被释放,会导致这个地址上的值不确定。
2、堆区
堆区一般由程序员自行开辟、回收。一般用new运算符来开辟一个堆区。
在上面这段代码中,func函数里的局部变量a在函数结束后就释放了(因为a保存在栈区中),但是释放之前,它将值传递给了main函数里的局部变量p,因此p保留了“10”这个数据在堆区中的地址,因此main函数里*p==10. main函数结束后,局部变量p也会被释放。
3、引用
C++里引用的实质是一个指针常量(因此无法改变它的值),int a=10,int& ref=a;表示ref恒等于a数值的地址。因此对ref进行的操作会直接影响到a实际的值,这与值传递不同(值传递是创建了一个拷贝副本用于存储a的值,对这个副本进行的操作对a实际的值无影响)。
此时可以直接认为,代码等效于int ref=a=10;也就是说ref和a实际上是同一个东西(都是存放10的那个地址),ref调用时不需要解引用(就像我们平时用int a=10时也不会解引用a)。
4、函数重载注意事项
4.1引用作为函数形参时
#include<iostream>
using namespace std;
void func(int& ref)
{
cout<<"func(int& ref) is called"<<endl;
}
void func(const int& ref)
{
cout<<"func(const int& ref) is called"<<endl;
}
int main()
{
int a=10;
func(a);
func(10);
return 0;
}
运行结果如下
这里需要注意:
(1)const int& 和int&属于不同变量类型,因此可以发生函数重载;
(2)第一个func(a)调用了func(int& ref),因为a是一个变量,它可读、可写,与int& ref一样(实参传入时int& ref=a),但是const int& ref只能读不能写;第二个func(10)不可能调用func(int& ref),因为实参传入过程中,int& ref=10,这个语法上就是错误的,而const int& ref=10没错,因为加入const后,编译器会修改代码,开辟一块内存int t=10;const int& a = t,这样语法就正确了。
4.2、函数重载遇到默认参数
上面两个函数在没有被调用的时候能发生函数重载,因为形参数量不同
但是函数被调用之后产生了二义性,因此无法确定调用哪个函数,故报错。
5、封装
5.1、三大权限的作用和区别
public、private、protected,后二者的区别是:子类不能访问父类中的private内容,但是可以访问父类中的protected内容。此三者类内均能访问,类外只能访问public类型。
#include<iostream>
using namespace std;
class Person{
public:
int age;
Person(int a,int h,int w){
age=a;
height=h;
weight=w;
}
protected:
int height;
private:
int weight;
};
int main()
{
Person p1(10,100,200);
cout<<p1.age;
//类外无法对p1.height和p1.weight做出任何操作
//即使是输出也不行,修改更不行。
}
5.2、class和struct的区别
5.3、成员设置为私有的优点
5.4、立方体类案例中,用成员函数判断两个立方体是否相等
注意:
(1)这个判断函数是成员函数,因此当前这个成员的长宽高都是已知的,只需传入想要判断的另一个立方体就行。
(2)传入的参数最好用引用传递,这样不用再拷贝一份。
5.5、点和圆的关系案例注意事项
(1)圆类中,圆心的类型应该定义为点类Pointer,这里用到了类的嵌套,需要注意;
(2)和5.4类似,如果isPointerInCircle定义在圆类中,那么这个方法的形参就只需传入需要判断的那个点,在主函数中则两个都要。
(3)set函数可以进行初始化,格式如下:
5.6、如何将每个类单独放到其它文件里
22 类和对象-封装-设计案例2-点和圆关系_哔哩哔哩_bilibili的20:30处开始
以上是文件point.cpp里的部分代码,可以看见m_X这些存在于class point里的变量都报错了,这是因为C中导入一个文件,默认将它放在代码区的前面,因此上面这些set、get等原point类的成员函数就被认为是全局函数了,而全局里并没有定义变量m_X。
为了解决这一问题,只需在函数名前面加上point : : ,表示这个函数是point作用域下的函数,也就是class point的成员函数。