• 类和对象——上



    类的定义

    看下面这个代码;

    class people
    {
    	char* name;
    	char* sex;
    	int age;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    class就是类的关键字。people就是这个类的名字,{}为类的主体,里面有成员,变量叫做成员变量,函数叫做成员函数
    c语言中的struct也可以作为类的关键字。只不过在c++中最好使用c++的class写法。

    struct people
    {
    	void print()
    	{
    		cout << "hello world\n";
    	}
    	int age;
    	char name[20];
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    类的定义有两种形式:
    一种是成员函数的声明和定义都在类的里面。
    另一种是类的里面是成员函数的声明,在另一个文件中实现类的定义。

    类的限定符

    类的限定符有:public(公有) protected(保护) private(私有)
    公有就是别人是可以访问的,
    私有就是别人不可以访问的。
    对于class的类默认访问权限是private。
    对于struct的类默认访问权限是public。

    struct people
    {
    	int age;
    	char name[20];
    };
    class p
    {
    	char* name;
    	char* sex;
    	int age;
    };
    int main()
    {
    	people a;
    	a.age;//这个可以访问
    	//p b;
    	//b.age;//这个就不可以访问
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    我们在实现类的时候,想给别人使用的就用public限定成共有的。不想让别人使用的就限制成私有的。

    class p
    {
    public:
    	void print()
    	{
    		cout << "hello world\n";
    	}
    private:
    	char* name;
    	char* sex;
    	int age;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    类的作用域

    类定义了新的定义域,里面的成员都属于该作用域。当在类的外面定义成员函数的时候,需要说明该成员的作用域。

    class p
    {
    public:
    	void print();
    private:
    	char* name;
    	char* sex;
    	int age;
    };
    void p::print()
    {
    	cout << "hello world\n";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    类的实例化

    实现了一个类,当这个类没有创建对象的时候,它在内存中是没有开辟空间的。
    类的实例化也就是用类创建对象。
    类的大小是怎么计算的呢?
    类的大小只需要计算成员变量的大小(计算方法和c语言的一样)。
    当类为空的时候,大小为1字节,只是为了占位。

    class Test
    {};
    int main()
    {
    	std::cout << sizeof(Test) <<std::endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    image.png
    而成员函数是放在公共代码区的,并不是在成员里面。

    class P
    {
    public:
    	void Print()
    	{
    		cout << "haha" << endl;
    	}
    
    };
    int main()
    {
    	P* ptr = nullptr;
    	ptr->Print();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    该程序照样是可以运行的。在第13行的时候,编译的时候根本就没有解引用去找成员,而是直接去公共代码区去找的该函数的地址。
    从下面编译的结果可以看出:
    image.png

    this指针

    看下面这个代码:

    class Date
    {
    public:
    	void Init(int year, int month, int day)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    	void Print()
    	{
    		cout << _year <<  ' '<<_month <<' '<< _day << endl;
    	}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    
    int main()
    {
    	Date a, b;
    	a.Init(1, 1, 1);
    	b.Init(2, 2, 2);
    	a.Print();
    	b.Print();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    image.png

    程序是怎么判断Init,Print是各自属于哪一个对象的?
    其实有一个this指针,C++编译器在非静态成员函数增加了隐形的指针参数,调用函数的时候其实把对象的地址传递给了this指针。
    this指针是编译的时候程序自己添加的,不需要我们自己手动添加。

    • this指针的特性:

    1.this指针的类型是类的类型*const
    2.this不能在参数中显示,但是可以在函数体中的成员变量中可以使用。
    3.this是成员函数的第一个隐形参数,存在栈区,因为是形参,具体存在哪里取决于编译器,不需要用户自己传递。
    看下面这个代码:Print1就可以正常的运行,而Print2并不能,就是因为Print2需要对空指针解引用。编译的时候不会出错,因为不会去类中去找这个函数。

    class Date
    {
    public:
    	void Print1()
    	{
    		cout << "Print1()" << endl;
    	}
    	void Print2()
    	{
    		cout << _year << endl;
    	}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    int main()
    {
    	Date* a = nullptr;
    	a->Print1();
    	a->Print2();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    2.JSP中c:if的使用
    【使用jquery编写第一个油猴(tempermonkey)脚本】
    【手撕STL】bitset(位图)、布隆过滤器
    Roson的Qt之旅 #112 QML布局之GridLayout(表格布局)
    Apache Paimon 使用之 Pulsar CDC 解析
    C++ 中的虚函数和多态性
    GPT-SoVITS音色克隆-模型训练步骤
    【软件测试】性能测试工具Loadrunner
    笔记二十二、使用路由state进行传递参数
    【愚公系列】2022年11月 .NET CORE工具案例-CSRedis执行Lua脚本实现商品秒杀
  • 原文地址:https://blog.csdn.net/m0_60598323/article/details/126045388