C++基础(2)——类和对象

编程入门 行业动态 更新时间:2024-10-15 06:18:05

C++基础(2)——类和<a href=https://www.elefans.com/category/jswz/34/1771306.html style=对象"/>

C++基础(2)——类和对象

目录

1. 类的引入:

2. 类的定义:

2.1类的定义以及基本结构:

2.2 类的访问限定符:

3. 类的声明与定义的分离:

4. 类的实例化:

5. 类的大小计算:


1. 类的引入:

      在数据结构系列的文章中,经常会使用结构体来构建例如顺序表,链表等数据结构的大体结构。在C语言中,结构体内部只能定义变量。但是在C++中,对结构体进行了修改,称之为类,类中不但可以定义变量,也可以定义函数。同时,类也兼容了C语言中结构体的所有用法。为了具体体现两种语言中结构体的不同,下面将通过一个示例进行解释:

     在数据结构的栈这一部分中,对于栈这一数据结构的定义可以由下面的代码表示:

struct Stack
{int* a;int top;int capacity;
};void StackInit(struct Stack* ps);void StackPush(struct Stack* ps, int x);

(注:此处只简单的引入栈的基本结构以及部分功能函数的声明,用于解释类和结构体的不同)

    在C语言中,如果不对结构体进行来重命名,则在使用时,必须带上。在C++中,对这部分进行了优化,在使用结构体时,只需要结构体名即可。例如对于上述代码,在C语言中,如果想要使用结构体,需输入

struct Stack S1;

而在C++中使用时,类名即类型,不需要加上。即:

Stack S1;

      上面提到了,在C++中,类(结构体)中可以定义函数,如果将开头关于栈的相关代码利用C++进行修改,可以很好的简化代码书写,即:

struct Stack
{int* a;int top;int capacity;void Init();void Push(int x);
};

        从上面给出的代码不难看出,利用C++对栈的相关代码进行改写时,不但让函数中的参数数量减少,并且还化简了C语言中与栈相关的功能函数的函数名。例如向栈中插入元素,C语言中此函数的函数名为,在C++中为。这是因为在C语言中,由于结构体内部不能定义函数,并且对于其他种类的数据结构中,均有初始化函数。如果不在函数名之前加上不同种类数据结构的名字加以区分,并且在C语言中并不存在函数重载。会造成错误。

       而在C++中,因为类的作用域(对于类的作用域将在文章后部给予相关解释,本处只是提出这个概念关系,并且可以在类中定义函数,因此,可以在不同的类中,同时定义

2. 类的定义:

2.1类的定义以及基本结构:

      上面给出了定义类的一个方法,即利用,本部分给出另一个用于定义类的关键字,具体结构如下:

class className
{
// 类体:由成员函数和成员变量组成
}; 

       其中,为定义类的关键字,为类的名字,{}中为类的主体,类主体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。

2.2 类的访问限定符:

  对于类的访问限定符,为,,

三者之间的区别为,修饰的成员变量可以在类外访问。而修饰的成员变量只能在类中被访问。

对于三个访问限定符的作用权限,可分为下面两种情况:

    1.如果任意访问限定符(例如下面给出代码中访问限定符)后面的代码中存在其他的访问限定符(例如下面代码中的),则的作用权限在遇到后截止。例如:

class Stack
{private:int* a;int top;int capacity;public:void Init();void Push(int x);
};

     2.如果任意的访问限定符(例如下面代码中的)中截止到类的"}"之前没有其他的访问限定符,则的访问权限作用截止到类的末尾。例如:

class Stack
{private:int* a;int top;int capacity;public:void Init();void Push(int x);
};

  对于这两个关键字都可以来定义类。二者的不同主要体现在默认的访问权限上,对于,其默认的访问权限为。对于,其默认的访问权限为。

3. 类的声明与定义的分离:

     在之前数据结构的章节中,经常会让函数的声明和定义分离在两个文件中,对于类而言,加入在类中给出一个函数的声明,在外部给出函数的定义,方法如下:

void Stack::Init()
{a = 0;top = 0;capacity = 0;
}

  除了上述情况,如果将函数的声明与定义同时放在类中,会出现两种情况:

1. 函数的代码行数较少,此时函数会自动变为内联函数。

2. 函数的代码行数较多,函数不会变成内联函数。

class Stack
{private:int* a;int top;int capacity;public:void Init();void Push(int x){a[top] = x;capacity++;top++;}
};

       因此,对于较为短小的函数,适合之间定义在类中,而较为复杂的函数适合采用声明与定义分离的方法。

4. 类的实例化:

  定义如下:用类类型创建对象的过程,称为类的实例化。类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类,并没有分配实际的内存空间来存储它。例如:

class Stack
{
public:int _year;int _month;int _day;
};

        在类中给出上面三个变量,需要注意,类中的变量,只是变量的声明,这种变量并没有在内存中开辟空间,在没有进行类的实例化的情况下,并不能进行使用,例如:

int main()
{Stack::_day = 2023;return 0;
}

        如果运行上述给出的代码,编译器会显示报错。这是因为此时的变量只是一个声明,并没有在内存中开辟空间。

      如果想要使用上述变量,首先需要进行一次类的实例化,代码如下:

int main()
{Stack Time; //实例化Time._day = 12;Time._month = 11;Time._year = 2023;return 0;
}

5. 类的大小计算:

例如对于下面给出的类:

class Stack1
{void Push(int x){}public:int _year;int _month;int _day;
};class Stack2
{public:int _year;int _month;int _day;
};

      不难发现,上述代码给出的两个类中,不同点为中包含了一个函数,中只声明了三个整型变量。通过下面的代码打印其大小:
 

int main()
{Stack1 time;Stack2 time1;cout << sizeof(time) << endl;cout << sizeof(time1) << endl;return 0;
}

结果如下:

       不难发现,二者大小的值是相同的,也就是说,计算类的大小时,并没有将类中的函数计算在内。这是因为,在每次调用时,类中的变量都会接收不同的值,而函数除了传递的形式参数没有任何变化,因此,在类中,变量是独立存储的,而函数,则是在一个公共空间中存储的。

       如果将上述的类进行部分更改,即:

class Stack3
{public:char _year;int _month;int _day;
};

 此时打印结果为:

通过打印结果不难发现,类中变量的存储依旧满足内存对齐原则,即:

1. 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的对齐数为8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。 

在类的大小这部分,还有一个特殊的例子,即空类:

class Stack4
{};

当打印空类的大小时,即:
 

int main()
{Stack4 a;cout << sizeof(a) << endl;return 0;
}

结果如下:

因此,对于上述无成员变量的类的对象(a),大小为1字节。这1字节并不存储有效数字,仅用来表示定义的对象(a)存在。

更多推荐

C++基础(2)——类和对象

本文发布于:2023-11-15 04:16:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1593505.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:对象   基础

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!