C++从入门到精通——类的作用域及类的实例化

2024-04-07 19:04

本文主要是介绍C++从入门到精通——类的作用域及类的实例化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

类的作用域及类的实例化

  • 前言
  • 一、类的作用域
  • 二、类的实例化
    • 引例
    • 类是对对象进行描述的
      • 示例
    • 一个类可以实例化出多个对象
      • 示例
    • 示例


前言

类的作用域是指类中定义的变量和方法的可见性和可访问性范围。在类的内部,所有成员(包括属性和方法)都具有类作用域,意味着它们可以在类的任何方法中被访问。然而,类的外部无法直接访问这些成员,除非通过类的实例或类本身(对于静态成员)。类的成员可以被设置为公有(public)、私有(private)或受保护的(protected),以控制其在不同上下文中的可见性和可访问性。这种作用域的控制有助于封装和隐藏类的实现细节,同时提供清晰的接口供外部使用。

类的实例化是指创建一个类的具体对象的过程。这通常涉及分配内存空间给新创建的对象,并设置其初始属性值。在实例化过程中,会调用类的构造函数来初始化对象的状态。一旦对象被实例化,就可以通过该对象来访问类的属性和方法,从而实现对对象的操作。类的实例化是面向对象编程中非常重要的概念,它使得程序员能够创建多个具有相同属性和方法的对象,并通过这些对象来模拟现实世界中的实体和它们之间的关系。


一、类的作用域

类的作用域是指类中定义的成员变量(属性)和方法可被访问的范围。

  • 类的作用域可以分为三个级别,分别为:

    • 公有作用域(public):公有作用域的成员变量和方法可以在类的外部被访问和调用。公有作用域的成员可以被其他类继承和重写。
    • 私有作用域(private):私有作用域的成员变量和方法只能在类的内部被访问和调用,无法被外部类或子类直接访问。私有作用域的成员只能被本类中的其他方法使用。
    • 受保护作用域(protected):受保护作用域的成员变量和方法可以在类的内部和子类中被访问和调用。受保护作用域的成员不能被外部类直接访问。
  • 类定义了一个新的作用域(即上述提到的三个作用域)
    类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。

using namespace std;
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int  _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " " << _gender << " " << _age << endl;
}

通过合理地使用作用域,可以控制类中成员的访问权限,提高代码的封装性和安全性。同时,类的作用域也可以使代码更加模块化,便于理解和维护。

二、类的实例化

用类的类型创建对象的过程,称为类的实例化

引例

#include<iostream>
using namespace std;
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int  _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " " << _gender << " " << _age << endl;
}
int main()
{Person man;cout << sizeof(man) << endl;cout << sizeof(Person) << endl;
}

在这里插入图片描述

#include<iostream>
using namespace std;
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int  _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " " << _gender << " " << _age << endl;
}
int main()
{Person man;cout << sizeof(Person) << endl;
}

在这里插入图片描述

#include<iostream>
using namespace std;
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int  _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " " << _gender << " " << _age << endl;
}
int main()
{cout << sizeof(Person) << endl;
}

在这里插入图片描述
通过这个我们可以发现许多问题

  • 为什么只算成员变量的空间而不算成员函数的空间

ps:类的存储空间的计算和结构体空间计算是一样的,不会计算结构体内存空间的可以看这篇文章——C语言从入门到实战——结构体与位段,也可以看我的下一篇文章

成员变量和成员函数在C++中是不同的概念,它们具有不同的存储方式和使用方式。

成员变量是对象的属性,用于存储对象的状态信息。它们在对象被创建时分配空间,并随着对象的销毁而释放空间。因此,我们在计算一个对象所占空间大小时,会考虑其中的成员变量。

成员函数是用来操作对象的行为,它们并不存储在对象内部,而是作为对象的一部分存在于对象所属的类中。成员函数的代码只有一份,被所有属于同一个类的对象共享。因此,计算对象所占空间时,并不考虑其中的成员函数。

此外,成员函数也不占用对象的存储空间,它们只是通过对象来进行调用。因此,成员函数并不会对对象的大小产生直接影响。

  • 为什么直接计算没有实例化的类的空间大小是存在的
    在计算机内存中,每个类的定义都占据一定的内存空间,即使没有实例化该类的对象。这是因为类定义中包含了类的成员变量、成员函数以及其他元数据信息,这些信息需要在内存中存储以供程序在运行时使用。
    类的成员变量在内存中按照定义顺序进行存储,每个成员变量占据一定的内存空间。成员函数的代码也需要在内存中存储,以便可以被调用执行。其他元数据信息如类名、类的继承关系、访问控制等也需要在内存中存储。
    即使没有实例化类的对象,也可以通过类名来访问静态成员变量和函数。这些静态成员变量和函数在内存中是独立存在的,因此需要占据一定的内存空间。
    所以,尽管没有实例化类的对象,但类的定义本身仍然需要占据一定的内存空间。这样可以确保程序在运行时可以正确访问和使用类的成员变量和函数。

类是对对象进行描述的

类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;比如:入学时填写的学生信息表,表格就可以看成是一个类,来描述具体学生信息。

类就像谜语一样,对谜底来进行描述,谜底就是谜语的一个实例。

谜语:“年纪不大,胡子一把,主人来了,就喊妈妈”

谜底:山羊

示例

可以在C++中定义一个类,但是不分配实际的内存空间来存储它。例如:

class MyClass {public:int myInt;void myMethod() {// do something}
};int main() {// 在这里定义一个MyClass对象,但没有分配内存空间存储它// 只是声明对象的存在,但不会分配内存空间MyClass myObject;// 通过访问成员变量和调用成员方法,可以使用对象的属性和行为myObject.myInt = 10;myObject.myMethod();return 0;
}

在这个例子中,我们定义了一个名为MyClass的类,并声明了一个MyClass类型的变量myObject,但并没有实际分配内存空间来存储它。在main()函数中,通过访问myObject的成员变量myInt和调用成员方法myMethod(),可以使用对象的属性和行为。然而,由于没有分配内存空间,这些操作只是模拟了对象的行为,实际上并没有真正的对象存在。

一个类可以实例化出多个对象

一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

int main()
{Person._age = 100;   // 编译失败:error C2059: 语法错误:“.”return 0;
}

Person类是没有空间的,只有Person类实例化出的对象才有具体的年龄。

示例

如下的例子是一个汽车类,每个汽车对象都可以有不同的颜色、品牌和型号。你可以创建多个汽车对象,每个对象都代表不同的车辆。

#include <iostream>
#include <string>class Car {
public:std::string brand;std::string model;std::string color;
};int main() {Car car1;car1.brand = "Toyota";car1.model = "Camry";car1.color = "Blue";Car car2;car2.brand = "Honda";car2.model = "Civic";car2.color = "Red";// 输出 car1 的属性std::cout << "Car 1:" << std::endl;std::cout << "Brand: " << car1.brand << std::endl;std::cout << "Model: " << car1.model << std::endl;std::cout << "Color: " << car1.color << std::endl;// 输出 car2 的属性std::cout << "Car 2:" << std::endl;std::cout << "Brand: " << car2.brand << std::endl;std::cout << "Model: " << car2.model << std::endl;std::cout << "Color: " << car2.color << std::endl;return 0;
}

这个例子中,我们定义了一个Car类,具有品牌(brand)、型号(model)和颜色(color)属性。我们创建了两个不同的Car对象car1car2,并为它们的属性赋值。然后,我们通过输出语句打印出每个汽车对象的属性。这样,我们可以实例化出多个不同的汽车对象。

示例

类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间
在这里插入图片描述
在这里插入图片描述


这篇关于C++从入门到精通——类的作用域及类的实例化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/883409

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多