Class Scope (类作用域) and C++11 Scoped Enumerations (C++11 作用域内枚举)

Class Scope [类作用域] and C++11 Scoped Enumerations [C++11 作用域内枚举]

  • 1. Class Scope Constants (作用域为类的常量)
  • 2. C++11 Scoped Enumerations (C++11 作用域内枚举)
  • References

Recall that you can use a variable with global scope anywhere in the file that contains its definition, whereas a variable with local scope is local to the block that contains its definition. Function names, too, can have global scope, but they never have local scope. C++ classes introduce a new kind of scope: class scope.
可以在全局变量所属文件的任何地方使用它,而局部变量只能在其所属的代码块中使用。函数名称的作用域也可以是全局的,但不能是局部的。C++ 类引入了一种新的作用域:类作用域。

Class scope applies to names defined in a class, such as the names of class data members and class member functions. Items that have class scope are known within the class but not outside the class. Thus, you can use the same class member names in different classes without conflict. Also class scope means you can’t directly access members of a class from the outside world. This is true even for public function members. That is, to invoke a public member function, you have to use an object.
在类中定义的名称 (例如类数据成员名和类成员函数名) 的作用域都为整个类,作用域为整个类的名称只在该类中是已知的,在类外是不可知的。因此,可以在不同类中使用相同的类成员名而不会引起冲突。类作用域意味着不能从外部直接访问类的成员,公有成员函数也是如此。要调用公有成员函数,必须通过对象。

Stock sleeper("Albert", 100, 0.25);  // create object
sleeper.Show();  // use object to invoke a member function

show();  // invalid - can't call method directly

Similarly, you have to use the scope-resolution operator when you define member functions (在定义成员函数时,必须使用作用域解析运算符):

void Stock::Update(const double price) {
	share_val_ = price;
	SetTot();
}

In short, within a class declaration or a member function definition you can use an unadorned member name (the unqualified name). A constructor name is recognized when it is called because its name is the same as the class name. Otherwise, you must use the direct membership operator (.), the indirect membership operator (->), or the scope-resolution operator (::), depending on the context, when you use a class member name.
在类声明或成员函数定义中,可以使用未修饰的成员名称 (未限定的名称)。构造函数名称在被调用时,才能被识别,因为它的名称与类名相同。在其他情况下,使用类成员名时,必须根据上下文使用直接成员运算符 (.) 、间接成员运算符 (->) 或作用域解析运算符 (::)

unadorned [ˌʌnəˈdɔːnd]:adj. 朴素的,简朴的,不加装饰的

1. Class Scope Constants (作用域为类的常量)

Sometimes it would be nice to have symbolic constants with class scope. For example, a class declaration might use the literal 30 to specify an array size. Because the constant is the same for all objects, it would be nice to create a single constant shared by all objects.
类声明可能使用字面值 30 来指定数组的长度,由于该常量对于所有对象来说都是相同的,因此创建一个由所有对象共享的常量是个不错的主意。

class Bakery
{
private:
    const int Months = 12;  // Failure
    double costs_[Months];
...

But this won’t work because declaring a class describes what an object looks like but doesn’t create an object. Hence, until you create an object, there’s no place to store a value.
但这是行不通的,因为声明类只是描述了对象的形式,并没有创建对象。因此,在创建对象前,将没有用于存储值的空间。

There are, however, a couple ways to achieve essentially the same desired effect.
有两种方式可以实现这个目标, 并且效果相同。

  • First, you can declare an enumeration within a class.

An enumeration given in a class declaration has class scope, so you can use enumerations to provide class scope symbolic names for integer constants.
第一种方式是在类中声明一个枚举。在类声明中声明的枚举的作用域为整个类,因此可以用枚举为整型常量提供作用域为整个类的符号名称。

class Bakery
{
private:
    enum {Months = 12};
    double costs_[Months];
...

Note that declaring an enumeration in this fashion does not create a class data member. That is, each individual object does not carry an enumeration in it. Rather, Months is just a symbolic name that the compiler replaces with 30 when it encounters it in code in class scope.
用这种方式声明枚举并不会创建类数据成员。也就是说,所有对象中都不包含枚举。另外,Months 只是一个符号名称,在作用域为整个类的代码中遇到它时,编译器将用 30 来替换它。

Because the Bakery class uses the enumeration merely to create a symbolic constant, with no intent of creating variables of the enumeration type, you needn’t provide an enumeration tag.
由于这里使用枚举只是为了创建符号常量,并不打算创建枚举类型的变量,因此不需要提供枚举名。

  • C++ has a second way of defining a constant within a class - using the keyword static.
class Bakery
{
private:
    static const int Months = 12;
    double costs_[Months];
...

This creates a single constant called Months that is stored with other static variables rather than in an object. Thus, there is only one Months constant shared by all Bakery objects.
这将创建一个名为 Months 的常量,该常量将与其他静态变量存储在一起,而不是存储在对象中。因此,只有一个 Months 常量,被所有 Bakery 对象共享。

2. C++11 Scoped Enumerations (C++11 作用域内枚举)

Traditional enumerations have some problems. One is that enumerators from two different enum definitions can conflict.
传统的枚举存在一些问题,其中之一是两个枚举定义中的枚举量可能发生冲突。

enum Egg {Small, Medium, Large, Jumbo};
enum Shirt {Small, Medium, Large};

This won’t fly because the Egg Small and the Shirt Small would both be in the same scope, and the names conflict. C++11 provides a new form of enumeration that avoids this problem by having class scope for its enumerators.
这将无法通过编译,因为 the Egg Small and the Shirt Small 位于相同的作用域内,它们将发生冲突。为避免这种问题,C++11 提供了一种新枚举,其枚举量的作用域为类。

enum class Egg {Small, Medium, Large, Jumbo};
enum class Shirt {Small, Medium, Large};

Alternatively, you can use the keyword struct instead of class. In either case, you now need to use the enum name to qualify the enumerator.
也可使用关键字 struct 代替 class。无论使用哪种方式,都需要使用枚举名来限定枚举量。

Egg first = Egg::Large;  // the Large enumerator of the Egg enum
Shirt second = Shirt::Large;  // the Large enumerator of the Shirt enum

Now that the enumerators have class scope, enumerators from different enum definitions no longer have potential name conflicts.
枚举量的作用域为类后,不同枚举定义中的枚举量就不会发生名称冲突了。

C++11 also tightens up type security for scoped enumerations. Regular enumerations get converted to integer types automatically in some situations, but scoped enumerations have no implicit conversions to integer types.
C++11 还提高了作用域内枚举的类型安全。在有些情况下,常规枚举将自动转换为整型,但作用域内枚举不能隐式地转换为整型。

enum Egg { Small, Medium, Large, Jumbo };  // unscoped
enum class Shirt { Small, Medium, Large };  // scoped
Egg one = Medium;  // unscoped
Shirt two = Shirt::Large;  // scoped

int king = one;  // implicit type conversion for unscoped
int ring = two;  // not allowed, no implicit type conversion

if (king < Jumbo)  // allowed
{
	std::cout << "Jumbo converted to int before comparison.\n";
}
if (king < Shirt::Medium)  // not allowed
{
	std::cout << "Not allowed: < not defined for scoped enum.\n";
}

But you can do an explicit type conversion if you feel you have to:

int three = int(Shirt::Small);  // three set to 0

Enumerations are represented by some underlying integer type, and under C98 that choice was implementation-dependent.Thus, a structure containing an enumeration might be of different sizes on different systems. C++11 removes that dependency for scoped enumerations. By default, the underlying type for C++11 scoped enumerations is int.
枚举用某种底层整型类型表示,在 C++98 中,如何选择取决于实现,因此包含枚举的结构的长度可能随系统而异。对于作用域内枚举,C++11 消除了这种依赖性。默认情况下,C++11 作用域内枚举的底层类型为 int

// underlying type for Pizza is short
enum class : short Pizza {Small, Medium, Large};

The : short specifies the underlying type to be short. The underlying type has to be an integer type. Under C++11, you also can use this syntax to indicate the underlying type for an unscoped enumeration, but if you don’t choose the type, the choice the compiler makes is implementation-dependent.
: short 将底层类型指定为 short底层类型必须为整型。在 C++11 中,也可使用这种语法来指定常规枚举的底层类型,但如果没有指定,编译器选择的底层类型将随实现而异。

References

[1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/
[2] C++ Primer Plus, 6th Edition, https://www.informit.com/store/c-plus-plus-primer-plus-9780321776402

  • Class Scope

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/760599.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[C++][设计模式][备忘录模式]详细讲解

目录 1.动机2.模式定义3.要点总结4.代码感受 1.动机 在软件构建过程中&#xff0c;某些对象的状态转换过程中&#xff0c;可能由于某中需要&#xff0c;要求程序能够回溯到对象之前处于某个点的状态。 如果使用一些公开接口来让其他对象得到对象的状态&#xff0c;便会暴露对象…

3D在线展览馆的独特魅力,技术如何重塑展览业的未来?

在数字化和虚拟现实技术迅猛发展的今天&#xff0c;3D在线展览馆已经成为一种颇具前景的创新形式。搭建3D在线展览馆不仅能够突破传统展览的时空限制&#xff0c;还能为参观者提供身临其境的体验&#xff0c;极大地提升展示效果和用户互动。 一、3D在线展览馆的意义 1、突破时空…

《Windows API每日一练》7.3 计时器时钟

知道如何使用Windows计时器之后&#xff0c;可以看看一些有用的计时器应用程序了。时钟是计时器最明显的应用&#xff0c;我们来看两个例子&#xff1a;一个是数字时钟&#xff0c;另一个是模拟时钟。 本节必须掌握的知识点&#xff1a; 第45练&#xff1a;7段数码管数字时钟 …

KV260视觉AI套件--PYNQ-DPU

目录 1. 简介 2. DPU 原理介绍 2.1 基本原理 2.2 增强型用法 3. DPU 开发流程 3.1 添加 DPU IP 3.2 在 BD 中调用 3.3 配置 DPU 参数 3.4 DPU 与 Zynq MPSoC互联 3.5 分配地址 3.6 生成 Bitstream 3.7 生成 BOOT.BIN 4. 总结 1. 简介 在《Vitis AI 环境搭建 &…

three.js - MeshPhongMaterial材质(实现玻璃水晶球效果)

1、概念 phong网格材质&#xff1a;Mesh - Phong - Material 一种用于具有镜面高光的光泽表面的材质。 它可以模拟&#xff0c;具有镜面高光的光泽表面&#xff0c;提供镜面反射效果。 MeshPhongMaterial&#xff1a; MeshPhongMaterial是一种基于Phong光照模型的材质&#…

Geeker-Admin:现代化的开源后台管理框架

Geeker-Admin&#xff1a;优雅管理&#xff0c;高效开发&#xff0c;尽在Geeker-Admin- 精选真开源&#xff0c;释放新价值。 概览 Geeker-Admin是一个基于Vue 3.4、TypeScript、Vite 5、Pinia和Element-Plus构建的开源后台管理框架。它为开发者提供了一套现代化、响应式的管理…

如何在Ubuntu20上离线安装joern(包括sbt和scala)

在Ubuntu 20上离线安装Joern&#xff0c;由于Joern通常需要通过互联网从其官方源或GitHub等地方下载&#xff0c;但在离线环境中&#xff0c;我们需要通过一些额外的步骤来准备和安装。&#xff08;本人水平有限&#xff0c;希望得到大家的指正&#xff09; 我们首先要做的就是…

【机器学习】Python sorted 函数

目录&#xff1a; 什么是sorted()函数列表降序排序应用到字符串自定义排序规则实际应用 Python中的内置函数——sorted()。 1. 什么是sorted()函数 在Python中&#xff0c;sorted()是一个内置函数&#xff0c;用于对任何可迭代对象&#xff08;如列表、元组、字符串等&…

jenkins 发布服务到linux服务器

1.环境准备 1.1 需要一台已经部署了jenkins的服务器&#xff0c;上面已经集成好了&#xff0c;jdk、maven、nodejs、git等基础的服务。 1.2 需要安装插件 pusblish over ssh 1.3 准备一台额外的linux服务器&#xff0c;安装好jdk 2.流程描述 2.1 配置jenkins&#xff0c;包括p…

每日一题——Python实现PAT乙级1090 危险品装箱(举一反三+思想解读+逐步优化)4千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 题目链接&#xff1a;https://pintia.cn/problem-sets/994805260223102976/exam/problems/typ…

LoadBalance 负载均衡

什么是负载均衡 负载均衡(Load Balance&#xff0c;简称 LB),是⾼并发,⾼可⽤系统必不可少的关键组件. 当服务流量增⼤时,通常会采⽤增加机器的⽅式进⾏扩容,负载均衡就是⽤来在多个机器或者其他资源中,按照⼀定的规则合理分配负载. 负载均衡的⼀些实现 服务多机部署时,开发⼈…

微积分-导数3(微分法则)

常见函数的导数 常量函数的导数 d d x ( c ) 0 \frac{d}{dx}(c) 0 dxd​(c)0 常量函数的图像是一条水平线 y c y c yc&#xff0c;它的斜率为0&#xff0c;所以我们必须有 f ′ ( x ) 0 f(x) 0 f′(x)0。从导数的定义来看&#xff0c;证明也很简单&#xff1a; f ′ …

44 - 50题高级字符串函数 / 正则表达式 / 子句 - 高频 SQL 50 题基础版

目录 1. 相关知识点2.例子2.44 - 修复表中的名字2.45 - 患某种疾病的患者2.46 - 删除重复的电子邮箱2.47 - 第二高的薪水2.48 - 按日期分组销售产品2.49 - 列出指定时间段内所有的下单产品2.50 - 查找拥有有效邮箱的用户 1. 相关知识点 相关函数 函数含义concat()字符串拼接upp…

MT6989(天玑9300)芯片性能参数_MTK联发科5G处理器

MT6989是联发科Dimensity旗舰系列的成员&#xff0c;旨在为旗舰5G智能手机供应商提供最先进的技术和性能。MT6989也是联发科目前最具创新和强大的5G智能手机芯片&#xff0c;具有领先的功耗效率&#xff0c;无与伦比的计算架构&#xff0c;有史以来最快和最稳定的5G调制解调器&…

MySQL之主从同步、分库分表

1、主从同步的原理 MySQL主从复制的核心是二进制日志 二进制日志&#xff08;binlog&#xff09;记录了所有DDL语句和DML语句&#xff0c;但不包括数据查询&#xff08;select、show&#xff09;语句。 1.1、复制分三步 master主库在事务提交时&#xff0c;会把数据变更记录…

九浅一深Jemalloc5.3.0 -- ②浅*size class

目前市面上有不少分析Jemalloc老版本的博文&#xff0c;但5.3.0却少之又少。而且5.3.0的架构与之前的版本也有较大不同&#xff0c;本着“与时俱进”、“由浅入深”的宗旨&#xff0c;我将逐步分析Jemalloc5.3.0的实现。 另外&#xff0c;单讲实现代码是极其枯燥的&#xff0c;…

mmap()函数和munmap()函数的例子

代码&#xff1a; #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #include <string.h> #include <stdio.h> #include <unistd.h>#define FILELENGTH 80 int main(void) {int fd-1;char …

Objective-C使用块枚举的细节

对元素类型的要求 在 Objective-C 中&#xff0c;NSArray 只能存储对象类型&#xff0c;而不能直接存储基本类型&#xff08;例如 int&#xff09;。但是&#xff0c;可以将基本类型封装在 NSNumber 等对象中&#xff0c;然后将这些对象存储在 NSArray 中。这样&#xff0c;en…

爬虫中如何创建Beautiful Soup 类的对象

在使用 lxml 库解析网页数据时&#xff0c;每次都需要编写和测试 XPath 的路径表达式&#xff0c;显得非常 烦琐。为了解决这个问题&#xff0c; Python 还提供了 Beautiful Soup 库提取 HTML 文档或 XML 文档的 节点。 Beautiful Soup 使用起来很便捷&#xff0c;…

Web后端开发概述环境搭建项目创建servlet生命周期

Web开发概述 web开发指的就是网页向后再让发送请求,与后端程序进行交互 web后端(javaEE)程序需要运行在服务器中 这样前端才可以对其进行进行访问 什么是服务器? 解释1: 服务器就是一款软件,可以向其发送请求,服务器会做出一个响应.可以在服务器中部署文件&#xff0c;让…
最新文章