一、类和对象
类由两部分构成:1.成员变量2.成员函数
C++中的struct兼容C的所有用法,同时C++中把struct升级成类
注意:类中的成员函数和成员数据都是声明,不是定义
类里的函数不是存到了对象中,而是存在公共区域(代码段)
类有两种定义方式:
1. 声明和定义全部放在类体中(成员函数如果在类中定义,编译器可能会将其当成内联函数处理)
class Person
{
public:
void show()
{
cout << _name << " " << _sex << " " << _age << endl;
}
private:
string _name;
string _sex;
int _age;
};
2. 声明放在.h文件中,类的定义放在.cpp文件中
//声明防在.h文件中
class Person
{
public:
void show();
private:
string _name;
string _sex;
int _age;
};
//定义放在类的实现文件中
void Person::show()
{
cout << _name << " " << _sex << " " << _age << endl;
}
二、访问限定符
C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
访问限定符有三种:public(公有)、protected(保护)、private(私有)
关于访问限定符的说明:
1.public修饰的成员在类外可以直接被访问
2.protected和private修饰的成员在类外不能直接被访问
3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现为止
4. class的默认访问权限为private,struct为public(因为struct要兼容C)注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别
三、类的实例化、类的大小
每个类成员实例化后,都是独立的空间,有自己的成员变量,但是每个对象调用的成员函数,都是同一个。
类的成员函数是存储在公共代码段的,在编译链接时,根据函数名去公共代码区找到函数的地址,根据函数地址使用地址(call函数地址)
这个程序的运行结果: 正常运行
因为show_id()是存在公共代码段的,编译链接时就找到了它的地址,调用它的地址了,所以是正常运行。
计算类的大小时,如果只有成员函数,则其大小是1,如果除了成员函数还有其他数据成员,则大小为数据成员内存对齐。 之所以大小是1,其不存储实际数据,只是标识对象存在。
四、类成员函数中的this指针
C++给每个“非静态成员函数“增加了一个隐藏的this指针,让其指向当前对象,在成员函数体中所有成员变量的操作,都将通过该指针访问。
注意:实参、形参位置不能显示传递和接收this指针,但是可以在成员函数内部使用this指针
this指针的特性:
1.this指针的类型:类类型*const
2.只能在成员函数的内部使用
3.this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参,所以对象中不存储this指针
4.this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递
那么:this指针存在哪里?this指针可以为空吗?
// 1.下面程序能编译通过吗?
// 2.下面程序会崩溃吗?在哪里崩溃
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
void Show()
{
cout<<"Show()"<<endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->PrintA();
p->Show();
}
p->PrintA();处会崩溃,因为其尝试访问成员变量_a,p指向nullptr,this指针对p这个空指针进行了解引用,产生了野指针问题,所以崩溃。
this指针是存在栈里的,因为它是一个形参