【C++渐入佳境(一)】作用域解析运算符::解说

🔔告示: 提供给编程爱好者。
🔋支持:
1.《『C/C++养成计划』C++中的双冒号::名解析(Scope Resolution Operator)》【CSDN】「AL」〖✿〗
🌌提供:
1. Dev Cpp 5.11(软件)【开源】「AL」〖✿〗
2. Dev Cpp 6.3(软件)【开源】「AL」〖✿〗
Devcpp配置文件位置: C:\Users\Lenovo\AppData\Roaming\Dev-Cpp
🌱环境:
1. g++ (tdm64-1) 4.9.2 | Copyright (C) 2014 Free Software Foundation, Inc.还不支持C11及以上标准.
2. gcc (Rev6, Built by MSYS2 project) 10.2.0 Copyright (C) 2020 Free Software Foundation, Inc.支持C14标准.

1️⃣介绍作用域解析运算符::

1️⃣⏺️1️⃣ 为什么要引入 ::

小蛙: "作用域解析运算符"听起来好唬人哦,这么长一串,有啥用武之地呢?
先知: 小友是否遇到过以下场景:
🚀

#include<iostream>
#include<cmath>

int abs = 0b1000;	// 二进制表示

int main()
{
	int abs = 1 << 3;	// 二进制(binary): 0001 左移三位 1000 
	std::cout << "函数中:" << abs << "  全局中:" << ::abs << std::endl;
	return 0;
}

小蛙: 这我知道,cmath库中有了abs()声明,而在demo.cpp的全局中又定义了abs名称是不合法的,而main()中定义的abs是合法的。
先知: 小友的分析的没错.
解说: C++中的"::"是作用域解析运算符(Scope Resolution Operator),它主要用于指定标识符(如变量名、函数名等)的作用域,并访问该作用域中的成员。这个运算符的引入主要是为了解决名称冲突和明确访问特定作用域中的成员

📓介绍: 引入::的目的
1.避免命名冲突: 在大型项目中,不同模块可能会定义相同名称的实体,使用 :: 可以明确指定要使用的实体,避免歧义。
2.访问控制: 在类和名称空间中,:: 允许访问私有或保护成员,这对于类的封装和数据隐藏至关重要。
3.明确性: 使用 :: 可以提高代码的可读性,让其他开发者清楚地知道某个实体的来源。
3.支持多重继承: 在支持多重继承的语言中,:: 可以用来解决基类名称冲突的问题。

1️⃣⏺️2️⃣ 作用域解析运算符::别称

小蛙:作用域解析运算符::有其他别称吗?
小夏: 常用别名如下:

别名英文作用
作用域操作符Scope Operator用于指定作用域的功能
类作用域解析器Class Scope Resolver类相关的作用域中使用
名称空间解析器Namespace Resolver名称空间中使用
全局作用域解析器Global Scope Resolver用于引用全局变量或函数
静态成员访问操作符Static Member Access Operator用于访问类的静态成员
作用域访问操作符Scope Access Operator

小蛙: 这么多别称,定会有不同的用武之地,好期待它们的艺术特色哦。



2️⃣名称空间与类作用域

2️⃣⏺️1️⃣ 名称空间的使用

小蛙: 很好奇C++中的"using namaspace std;"中的std是如何定义的。

大灰: 其实很简单的哦!

小夏: 例一:命名空间限定符(Namespace qualifier)::"间接"访问空间成员

#include<iostream>
namespace XiaXin{
	// 命名空间中可以定义变量/函数/结构体/类/模版/... 
	int rand = 10;
	int Add(int left, int right){
		return left + right;
	}
	struct Node{
		struct Node* next;
		int val;
	};
}

int main()
{
	std::cout << "a=" << XiaXin::rand << std::endl << "10+20=" << XiaXin::Add(10,20);
	return 0;
}

mome: XiaXin::就是XiaXin的命名空间前缀.像是把买的的零食都放在箱子里面,再挑自己想要吃的。这样房间整洁啦,但得挑零食。

小夏: 例二:命名空间指令(Namespace directive)"直接"访问空间成员

#include<iostream>
using namespace std;	// std空间成员"扩展"到全局 
namespace XiaXin{
	// 命名空间中可以定义变量/函数/结构体/类/模版/... 
	class Cat{
		int age;
	public:
		void actoin(){
			cout << "小猫一顿吃小鱼" << endl;
		}
	};
	enum Animal{
		Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Goat, Monkey, Rooster, Dog, Pig 
	};
}
using namespace XiaXin;		// XiaXin空间成员"扩展"到全局 
int main()
{
	Cat().actoin();	
	Animal zoon;
	cout << zoon;
	return 0;
}

小蛙: 这种方法果真神奇,就像把装零食的箱子打开再倒在地面上,直接取就行啦,这样取零食就不用翻腾半天了才找到想吃的了,但样房间就凌乱了。

小夏: 例三:命名空间指令与命名空间限定符交叉使用

#include<iostream>

namespace XiaXin{
	// 命名空间中可以定义变量/函数/结构体/类/模版/... 
	unsigned initTimes = 0;		// 类实例化次数 Instantiation times
	template <typename T>
    class MyTemplateClass {
    private:
        T data;
    public:
        MyTemplateClass(const T& d) : data(d) { initTimes += 1;}
        
        T getData() const {
            return data;
        }
        void setData(const T& d) {
            data = d;
        }
    };
}
using XiaXin::initTimes;	// XiaXin空间成员initTimes"扩展"到全局 
int main()
{
	std::cout << "该类被实例化的次数: " << initTimes << std::endl;
	std::cout << XiaXin::MyTemplateClass<std::string>("XiaXin").getData() << std::endl;
	std::cout << "该类被实例化的次数: " << initTimes << std::endl;
	return 0;
}

大灰: 这样使用即兼顾了整体的规范又"开放"了常用成员(可直接使用)。就像箱子里面的零食,不是全部倒出来,而是提前取自己喜欢吃的口味出来,这样房间不会过于邋遢,爱吃的零食可以直接取。

小夏: 例四:名称空间"扩展"到名称空间

#include<iostream>

namespace XiaXin{
//	using namespace std;		合法 
	template<typename T>
    class MyTemplateClass {
//    	using std::cout;		不合法 
    private:
        T data;
    public:
    	MyTemplateClass(const T& d):data(d) {};
        T getData() const{
        	return data;
		}
    };
}
int main()
{	
	std::cout << XiaXin::MyTemplateClass<std::string>("XiaXin").getData() << std::endl;
	return 0;
}
⚠️注意:
1. 名称空间不能"扩展"到局部区域(类、函数)中.
2. 名称空间可以"扩展"到名称空间中.
✨总结:
1. 大型项目,不建议将名称空间的内容"扩展"到全局。 名称空间名::成员名;
2. 日常练习代码建议将名称空间的内容"扩展"到全局。 using namespace 名称空间名;
3. 小项目,部分常用的名称空间的内容"扩展"到全局。 using 名称空间名::成员名;
4. 名称空间内容"扩展"到名称空间。

解说:
1. namespace 空间名称{成员}: 形象为约束空间成员局部化、保留空间成员在局部
2. using namesapce 空间名称;: 可以形象为空间成员扩展全局化、释放空间成员到全局,外部直接访问空间中的内容。
3. 空间名称::成员名: 形象为通过空间名访问内部成员、间接使用空间中的内容


2️⃣⏺️2️⃣ 类作用域的使用

小蛙: 类中的成员分三类:有私有成员、受保护成员、公共成员。

1. 类作用域使用范例

#include <iostream>
#include <string>

// 定义一个类
class Employee {
private:
    std::string name; // 私有成员
    int age;          // 私有成员

public:
    Employee(const std::string& empName, int empAge) : name(empName), age(empAge) {}

    // 成员函数,用于设置员工名字
    void setName(const std::string& empName) {
        name = empName;
    }

    // 成员函数,用于获取员工名字
    std::string getName() const {
        return name;
    }

    // 成员函数,用于设置员工年龄
    void setAge(int empAge) {
        age = empAge;
    }

    // 成员函数,用于获取员工年龄
    int getAge() const {
        return age;
    }
};

int main() {
    Employee emp("John Doe", 30);

    // 访问公有成员函数
    emp.setName("Jane Doe");
    std::cout << "Employee Name: " << emp.getName() << std::endl;
    emp.setAge(35);
    std::cout << "Employee Age: " << emp.getAge() << std::endl;

    // 无法直接访问私有成员
    // std::cout << "Employee Name: " << emp.name << std::endl; // 错误:'name' is private
    // std::cout << "Employee Age: " << emp.age << std::endl;   // 错误:'age' is private

    return 0;
}

2. 名称空间与类的结合使用

#include <iostream>
#include <vector>

// 定义一个名称空间
namespace MyLibrary {
    // 在名称空间内定义一个类
    class MyClass {
    private:
        int value;
    public:
        MyClass(int val) : value(val) {}
        // 成员函数,用于获取值
        int getValue() const {
            return value;
        }
        // 成员函数,用于设置值
        void setValue(int val) {
            value = val;
        }
    };

    // 在名称空间内定义一个模板类
    template <typename T>
    class MyTemplateClass {
    private:
        T data;
    public:
        MyTemplateClass(const T& d) : data(d) {}

        T getData() const {
            return data;
        }
        void setData(const T& d) {
            data = d;
        }
    };
}

int main() {
    // 使用名称空间中的类
    MyLibrary::MyClass myObj(42);
    std::cout << "MyClass value: " << myObj.getValue() << std::endl;
    myObj.setValue(24);
    std::cout << "MyClass value after setting: " << myObj.getValue() << std::endl;

    // 使用名称空间中的模板类
    MyLibrary::MyTemplateClass<std::string> templateObj("Hello, World!");
    std::cout << "TemplateClass data: " << templateObj.getData() << std::endl;
    templateObj.setData("New Data");
    std::cout << "TemplateClass data after setting: " << templateObj.getData() << std::endl;

    return 0;
}

3. 名称空间的多重定义和链接

// file1.cpp
namespace MyNamespace {
//    int globalValue = 100;
	int file1_globalValue = 100; 
}

// file2.cpp
namespace MyNamespace {
//    int globalValue = 200; // 合法,但链接时会出错,因为存在多个定义
	int file2_globalValue = 200;
}

// main.cpp
#include <iostream>

// 引入两个文件的名称空间
extern "C" {
    int file1_globalValue;
    int file2_globalValue;
}

int main() {
    // 链接错误:全局变量重定义
    std::cout << "Global value from file1: " << file1_globalValue << std::endl;
    std::cout << "Global value from file2: " << file2_globalValue << std::endl;

    return 0;
}

2️⃣⏺️3️⃣ 名称空间和类作用域的同与异

解说:
(1) 在C++中,名称空间(namespace)和类的作用域(class scope)都是用来组织代码和避免名称冲突的机制.
(2) 在实际使用中,名称空间通常用于库的组织,而类作用域用于定义数据结构和行为。例如,类不能在多个地方定义,否则会导致链接错误
(3) 在实际编程中,通常需要根据具体需求来选择使用名称空间还是类作用域,或者两者结合使用,以实现代码的组织和封装。

内容名称空间类作用域
目的用于将全局名称(函数、变量、类型等)组织到一个命名空间中,以避免全局名称冲突用于定义类的成员(包括数据成员和成员函数),以及控制成员的访问权限(公有、私有、保护)
作用范围可以包含整个文件或代码块中的所有声明仅限于类定义内部
访问控制没有访问控制的概念,名称空间中的所有成员都是公开的有严格的访问控制,成员可以是公有的、私有的或保护的
使用方式使用using声明或using指令来引入特定的名称或整个名称空间通过类名和作用域解析运算符(::)来访问类的成员
成员的可见性名称空间中的成员默认是全局可见的,但通常通过名称空间限定符来限定类的成员默认是不可见的(私有或保护),除非明确声明为公有
名称解析在编译时进行名称解析,如果存在名称冲突,编译器会报错在编译时和运行时都进行名称解析,因为类的成员可以是动态绑定的(如虚函数)
多重定义名称空间可以有多个定义,但它们必须完全相同,否则会导致链接错误类只能定义一次,多重定义会导致编译错误
模板模板可以定义在名称空间中,但模板实例化时需要指定完整的名称空间模板可以定义在类内部,也可以定义在类外部
继承名称空间不支持继承,但可以包含多个名称空间类支持继承,子类可以继承父类的公有和保护成员
多重定义和链接名称空间的多重定义是合法的,只要它们是一致的类不能在多个地方定义,否则会导致链接错误

2️⃣⏺️4️⃣ "std::"与"类名::"的同与异

解说: std::
(1) std:: 是 C++标准库的名称空间(namespace)的缩写.
(2) std 代表 Standard Library,即标准库.
(3) 它包含了标准库中定义的所有类型、函数、对象和其他名称空间.
(4) 使用 std:: 是为了访问标准库中定义的名称,以避免命名冲突.

解说: 类名::
(1) 类名:: 是用来访问类内部的成员(包括数据成员和成员函数).
(2) 它表明后面跟着的名称是类的一个成员.
(3) 使用 类名:: 是为了访问或指定某个类中定义的特定成员.

内容名称空间类作用域
所属范围用于访问整个标准库名称空间中的名称用于访问特定类中的成员
目的用于区分全局名称空间中的名称和标准库中的名称用于区分类内部的成员和全局名称空间中的名称
作用域作用于整个程序,因为它是全局名称空间的一部分作用于特定的类定义内部
成员访问后面通常跟的是标准库中的类型(如 std::vector)、函数(如 std::sort)或对象(如 std::cout)后面跟的是类中的成员变量(如 ClassName::memberVar)或成员函数(如 ClassName::memberFunc())
内容区别
上下文根据代码的上下文来判断。如果代码是在引用标准库中的类型或函数,那么很可能是 std::。如果是在引用某个类定义中的成员,那么很可能是 类名::
定义位置std:: 后面跟的名称是在标准库的头文件中定义的,而 类名:: 后面跟的名称是在类的定义中定义的
编译器提示如果编译器提示找不到名称,可以尝试添加 std:: 前缀,如果问题解决,那么就是标准库中的名称
编译器提示如果编译器提示找不到名称,可以尝试添加 std:: 前缀,如果问题解决,那么就是标准库中的名称std:: 没有解决问题,那么可能是类中的成员,需要使用 类名::
文档和头文件查看相关的文档或头文件,了解名称是在哪个名称空间或类中定义的

2️⃣⏺️5️⃣ 名称空间与类的同与异

解说: 名称空间(Namespace)
(1) 名称空间是一个定义了一组名字的区域,用于组织代码和避免名称冲突.
(2) 名称空间可以包含变量、函数、类、枚举和其他名称空间.
(3) 名称空间的声明通常使用 namespace 名称 { … } 的形式.

解说: 类(Class)
(1) 类是面向对象编程中的基本构造块,用于创建具有数据和功能的自定义数据类型.
(2) 类可以包含数据成员(变量)、成员函数(方法)、静态成员、常量成员等.
(3) 类的声明通常使用 class 类名 { … } 或 struct 类名 { … } 的形式.

内容名称空间
定义的内容名称空间用于定义一组名字,这些名字可以是任何类型,包括类、函数、变量等类用于定义一种数据类型,包含数据和操作这些数据的方法
目的名称空间的主要目的是避免全局名称空间的污染和名称冲突类的主要目的是封装数据和行为,实现面向对象编程
成员访问名称空间中的成员可以通过 namespace::成员名 的方式访问类的成员可以通过 类名::成员名 的方式访问
作用域名称空间可以跨越多个文件和模块类的作用域通常局限于定义它的文件或模块
成员的可见性名称空间中的成员默认是全局可见的,但通常通过名称空间限定符来限定类的成员可以是公有的、私有的或保护的,具有更严格的访问控制
内容区别
上下文根据代码的上下文来判断。如果代码是在引用标准库中的类型或函数,那么很可能是 std::。如果是在引用某个类定义中的成员,那么很可能是 类名::
定义位置名称空间的定义通常在文件的顶部或单独的头文件中,而类的定义通常在实现文件中
语法名称空间的定义使用 namespace 关键字,类的定义使用 class 或 struct 关键字
成员类型名称空间可以包含任何类型的成员,而类的成员通常是数据成员和成员函数

3️⃣作用域解析运算符 :: 的应用场景

3️⃣⏺️1️⃣ 作用域解析操作符应用场景

解说:
(1) 在C++中,作用域解析运算符 :: 用于明确指出某个实体(如变量、函数、类成员等)属于哪个作用域。这个运算符是C++语言的核心组成部分之一,用于解决作用域相关的各种问题。
(2) 在C++中,作用域解析运算符 :: 用于指定程序中某个实体的完整名称,包括其所属的作用域。它允许开发者明确指出他们想要引用的变量、函数、类型或其他实体的确切位置。

内容区别
访问类成员访问公有成员:ClassName::memberFunction()
访问私有或保护成员(在类定义内部或友元函数中):ClassName::privateMember
访问名称空间成员namespaceName::function()
namespaceName::variable
全局名称空间中的名称如果有多个名称空间定义了相同名称的实体,可以使用 :: 来指定全局名称空间中的实体:::globalFunction()
模板实例化当模板类或函数在名称空间中时,需要使用 :: 来指定模板实例化的位置:namespaceName::templateName<type>
静态成员访问访问类的静态成员:ClassName::staticMember
枚举类型访问枚举类型的成员:enumName::enumValue
类型定义使用 :: 来引用某个类型定义:typedef struct { int x; } ::TypedefName
友元类和友元函数声明友元类或友元函数时,使用 :: 来指定友元:friend void ClassName::friendFunction()
多重继承在派生类中,使用 :: 来区分来自不同基类的成员:BaseClassName1::member1 和 BaseClassName2::member2
命名捕获在lambda表达式中,使用 :: 来捕获所有外部变量:[](int x) { return ::capturedVar + x; }
类型转换使用 :: 进行静态类型转换:ClassName::PointerType pointer = dynamic_cast<ClassName::PointerType>(basePointer)
命名空间别名使用 :: 结合命名空间别名:using namespaceName::AliasName
类模板参数在类模板中,使用 :: 来引用模板参数:template void Function(T::NestedType param)
继承中的类型访问在派生类中,使用 :: 来访问基类的类型:BaseClassName::Type member;
匿名名称空间在匿名名称空间中使用 :: 来访问成员:namespace { int var; } ::var
覆盖基类成员在派生类中使用 :: 来明确指出要覆盖的基类成员:void DerivedClass::memberFunction() override { BaseClass::memberFunction(); }
委托构造函数在类的构造函数初始化列表中使用 :: 来委托给另一个构造函数:DerivedClass::DerivedClass() : BaseClass::BaseClass() { }
命名空间中的类型定义当名称空间中定义了类型别名或模板实例化时,使用 :: 来引用:using IntVector = std::vector<int>; IntVector vec;
异常处理在抛出异常时,使用 :: 来指定抛出的类型:throw std::runtime_error("Error occurred");
强制类型转换使用 C++ 风格的强制类型转换时,可能需要使用 :::int* pi = reinterpret_cast<int*>(ptr);
嵌套名称空间访问嵌套名称空间中的成员:namespaceName1::namespaceName2::function()
成员模板在类模板中访问成员模板:OuterClass::template InnerTemplate<int>
全局函数模板在模板参数中引用全局模板:template void Function(T::template NestedTemplate param)
类型萃取在模板元编程中,使用 :: 来萃取类型:using Type = typename BaseClass::template NestedType<int>;
强制基类访问在派生类中强制访问基类的覆盖成员:BaseClass::memberFunction();
初始化列表中的成员访问在类的初始化列表中访问成员:DerivedClass::DerivedClass(int x) : BaseClass(x), member_(x) { }
运算符重载在运算符重载中使用 :: 来指定运算符的左侧操作数:ReturnType ClassName::operator()(const ArgType& arg) const { ... }
嵌套类定义在类中定义嵌套类,并使用 :: 来引用:class OuterClass { class InnerClass { ... }; };
使用声明在使用声明中使用 :: 来引入名称空间或类的成员:using std::cout;
定义嵌套类成员在类定义中定义嵌套类的成员:class OuterClass::InnerClass { ... };
静态断言使用 :: 在类定义中进行静态断言:static_assert(sizeof(int) == 4, "Error message");
类型特征使用类型特征(type traits)时,使用 :: 来访问特征类型:std::is_same<BaseClass::Type, DerivedClass::Type>::value
using 声明在类或名称空间中使用 using 声明来引入基类或名称空间的成员:using BaseClass::memberFunction;
内联成员定义在类定义中直接定义成员函数:ReturnType ClassName::memberFunction() { ... }
类型别名模板定义类型别名模板:template <typename T> using PtrType = T*;
访问控制在类定义中使用 :: 来改变成员的访问级别:public: ClassName::PublicMember;
虚函数表在讨论类的布局或内存模型时,:: 可以用于讨论虚函数表(vtable)的成员。
修饰符使用修饰符(如 final 或 sealed)时,使用 :: 来修饰类或成员:class FinalClass final { ... };
模块化编程在模块化编程中,:: 用于引用不同模块中的实体

3️⃣⏺️2️⃣ 作用域解析操作符应用实例

解说: 在C++中,作用域解析运算符 :: 用于指定程序中某个实体的完整名称,包括其所属的作用域。它允许开发者明确指出他们想要引用的变量、函数、类型或其他实体的确切位置。

1. 类成员访问

mome: 在类外部,当需要访问类的成员时,可以使用 :: 后跟成员的名称。如果成员是公有的,可以在类实例之外使用 :: 来访问。可以使用"::"来访问类的成员变量或成员函数,包括静态成员。这允许在不创建类对象的情况下访问静态成员.

class MyClass {  
public:  
    static int static_variable;  
    int member_variable;  
    void member_function();  
};  
  
int MyClass::static_variable = 10; // 声明静态成员变量  
  
void MyClass::member_function() {  
    // 成员函数实现  
}  
  
int main() {  
    MyClass::static_variable++; // 访问静态成员变量  
    // 注意:访问非静态成员变量需要类对象  
}

2. 静态成员访问

小蛙: 静态成员属于类本身,而不是类的某个特定实例。可以通过类名和 :: 来访问。

int value = Example::staticMember;

3. 全局名称空间中的实体访问

小蛙: 如果在局部作用域(如函数内部)中有一个与全局作用域中的实体同名的实体,可以使用 :: 来明确引用全局实体。

int value = Example::staticMember;

4. 名称空间成员访问

mome: 名称空间用于将程序的不同部分组织成逻辑组。可以使用 :: 来访问名称空间中的成员。

namespace MyNamespace {
    int myVar = 5;
}
int main() {
    std::cout << MyNamespace::myVar; // 输出名称空间中的变量
    return 0;
}

5. 枚举类型成员访问

mome: 枚举类型的成员可以通过枚举名和 :: 来访问

enum Color { Red, Green, Blue };
Color col = Color::Green;

6. 类型转换

mome: 在C++中,dynamic_cast 和 static_cast 等类型转换运算符在使用时,如果转换的目标类型是当前类的基类或成员,需要使用 ::.

Base* b = new Derived;
Derived* d = dynamic_cast<Derived*>(b);

7. 友元类和友元函数

mome: 声明友元类或友元函数时,可以使用 :: 来指定它们属于哪个类或名称空间.

class Friend {
public:
    friend class MyClass;
    friend void myFriendFunction();
};

8. 嵌套类

mome: 嵌套类(或嵌套名称空间)的成员可以通过外部类的名称和 :: 来访问.

class Outer {
public:
    class Inner {
        int innerVar;
    };
};
int outerVar = Outer::Inner::innerVar;

9. 多重继承

mome: 在多重继承的情况下,可以使用 :: 来区分来自不同基类的成员.

class Base1 {
public:
    void base1Func() {}
};

class Base2 {
public:
    void base2Func() {}
};

class Derived : public Base1, public Base2 {
};

void callFunc(Derived& d) {
    d.base1Func(); // 调用 Base1 的成员
    d.Base2::base2Func(); // 调用 Base2 的成员
}

10. 命名空间别名

mome: 当使用 namespace 声明别名时,可以使用 :: 来引用别名.

namespace MyNS = MyNamespace;
int value = MyNS::myVar;

11. 模板特化

mome: 在模板特化中,可以使用 :: 来指定特化的模板参数.

namespace MyNamespace {
    template <typename T>
    class MyTemplateClass {};
}
MyNamespace::MyTemplateClass<int> myObject;  // 使用 Scope Resolution Operator 模板实例化
template<typename T>  
class MyTemplate {  
public:  
    static void my_method() {  
        // 方法实现  
    }  
};  
  
void func() {  
    MyTemplate<int>::my_method(); // 访问模板类的int实例化中的方法  
}

12. 在类外定义成员函数

mome: 当成员函数的实现在类定义之外,需要使用 :: 来指明该函数属于哪个类.

class MyClass {
public:
    int getValue();
};
int MyClass::getValue() {  // 使用 Scope Resolution Operator 在类外定义成员函数
    return 42;
}

13. 访问全局变量或函数

mome: 当局部作用域中存在与全局作用域同名的实体时,可以使用 :: 来访问全局实体.

int globalVar = 10;
void function() {
    int globalVar = 20;
    std::cout << ::globalVar;  // 输出全局变量的值
}

4️⃣作用域解析运算符 :: 的使用场景与其声明周期

4️⃣⏺️1️⃣作用域解析运算符 :: 的使用场景与其声明周期

解说: 生存周期通常指的是对象的创建、存在和销毁的整个过程.

内容含义举例
全局变量或函数全局变量和函数的生存周期从它们被定义在代码中的静态存储区开始,直到程序结束使用 :: 来访问全局变量:int value = ::globalVar;
静态成员变量静态成员变量的生存周期与全局变量类似,它们在程序开始时分配内存,在程序结束时释放int MyClass::staticVar = 0;
静态成员函数静态成员函数的生存周期与全局函数类似,它们在程序的整个运行期间都存在void MyClass::staticFunction() { /* ... */ }
实例成员变量实例成员变量的生存周期与其所依附的对象相同,当对象被创建时它们被分配内存,当对象被销毁时它们被释放int MyClass::memberVar; 在 MyClass 对象创建时初始化
实例成员函数实例成员函数的生存周期与全局函数类似,但它们的作用域是与类实例绑定的void MyClass::memberFunction() { /* ... */ } 在对象创建后可以被调用
构造函数和析构函数构造函数和析构函数与它们构造或析构的对象的生存周期紧密相关MyClass::MyClass() { /* 构造代码 */ } 和 MyClass::~MyClass() { /* 析构代码 */ }
命名空间名称空间的生存周期贯穿整个程序,名称空间本身没有生存周期,但名称空间中的实体(如变量、函数)有namespace MyNamespace { int myVar; }
枚举枚举类型的生存周期与全局类型相同,从定义开始到程序结束enum Color { Red, Green, Blue }; Color col = Color::Green;
模板实例化模板的生存周期与全局函数类似,但模板实例的生存周期可能与使用该实例的对象相关template <typename T> class MyClass; 和 MyClass<int> myObject;
友元函数或友元类友元函数的生存周期与全局函数相同,友元类的生存周期与全局类相同friend void friendFunction();
嵌套类嵌套类的生存周期与包含它的类的对象相同class Outer { class Inner; };
匿名对象匿名对象的生存周期通常仅限于创建它们的表达式或语句的执行int result = (::func())(); 这里的 ::func() 创建了一个匿名对象
✨总结:
1. 在C++中,使用 :: 来访问这些不同实体时,它们的生命周期是由它们在程序中的角色和定义的位置决定的。全局和静态实体通常有程序的整个生存周期,而局部和实例实体的生存周期则与它们所在的作用域或对象的生命周期相关。

📖原文: 吟安一个字,捻断数茎须。 ---唐·贾岛《题诗后》
⌛悠然: 为了选择最恰当的字眼,表现出最美的意境。


🪁 Lumin looks forward to seeing you again 🌌

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值