文章目录
- 一、类的定义
- 1. 声明和定义全部放在类体中
- 2.声明和定义分离
- 二、类的访问限定符及封装
- 三、类的实例化
- 四、 类对象的存储方式
- 五.this指针
- 1.简单应用
- 2、问题思考
一、类的定义
class className
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。
在c语言中,仅支持的自定义类型为struct,且结构体成员仅为数据变量。
在c++在保留了,struct且拓展了class,结构体内不仅可以定义变量,也可以定义函数。
类的两种定义方式:
1. 声明和定义全部放在类体中
需注意:成员函数如果在类中定义,编译器可能会将其当成内
联函数处理。
class person {
public:void ShowInfo(){cout <<_name<<_sex<<_age << endl;}
public:char* _name;char* _sex;int _age;
};
2.声明和定义分离
注意:成员函数名前需要加类名::
头文件:
class person {
public:void ShowInfo();
public:char* _name;char* _sex;int _age;
};
源文件
void person::ShowInfo()
{
cout <<_name<<_sex<<_age << endl;
}
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。
二、类的访问限定符及封装
【访问限定符说明】
- public修饰的成员在类外可以直接被访问
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
- 如果后面没有访问限定符,作用域就到 } 即类结束。
- class的默认访问权限为private,struct为public(因为struct要兼容C)
三、类的实例化
类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设
计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间
int main()
{Person._age = 100; // 编译失败:error C2059: 语法错误:“.”return 0;
}
如上所示:erson类是没有空间的,只有Person类实例化出的对象才有具体的年龄。
四、 类对象的存储方式
按照类的形式应该将将成员函数的地址和成员变量都存在对象中
但是 存在问题:调的成员函数都是一样的,所以没必要都每个对象都存一个成员函数的地址。造成内存浪费。
所以在实践中为了节约空间将成员函数放在公共代码区,使用时直接调用,每个对象的成员函数地址都是相同的。‘
五.this指针
1.简单应用
在C++中,this指针是一个隐含的指向当前对象的指针,它是每个非静态成员函数的一个隐含参数。
通俗的说就是成员函数中的对象,会默认传入函数中,在一个类中可直接调用无需单独传参。
他有如下特点:
1.this指针是一个指向当前对象的指针,它指向调用该成员函数的对象。
2.this指针是一个常量指针,不能被修改。
3.this指针在每个非静态成员函数中都是可用的,它指向调用该成员函数的对象
用法:
1.在成员函数中可以使用this指针来访问对象的成员变量和成员函数,
以区分局部变量和成员变量同名的情况。
2.可以通过this指针返回对象本身,从而支持链式调用。
3。可以在类的成员函数中将this指针作为参数传递给其他函数,
以便在其他函数中访问当前对象。
2、问题思考
- this指针储存在哪里?
在C++中,this指针并不是实际存储在对象中的成员变量中,而是在编译器内部进行处理的。当调用一个成员函数时,编译器会将对象的地址作为隐含的参数传递给成员函数,并将该地址赋给this指针。因此,this指针并不占用对象的内存空间,它只是一个指向调用该成员函数的对象的指针。
所以显然存储在编译器中栈的位置,某些编译器会直接放在寄存器中,使得高效编译 - 以下两个程序运行时分别是什么结果?
Question1:
class test1 {
public:void print(){cout << "print()" << endl;}
private:int a = 100;
};
int main()
{test1* t1=nullptr;t1->print();return 0;
}
Question 2:
class test2 {
public:void print(){a = 2024;cout << a << endl;}
private:int a = 100;
};
int main()
{test2* t2=nullptr;t2->print();return 0;
}
这两个程序的区别在通过空指针调用函数时是否访问了成员变量,
看似都犯了对空指针解引用的操作错误,实则,底层调用函数时并不需要解引用而是去之前我们提到的公共代码区,所以test1运行正常,而test2由于使用了this指针去调用成员变量则会运行崩溃。