全局作用域成员

本文详细介绍了Node.js中的全局对象global、process和console的功能与用途,并解释了如何使用这些对象进行输入输出操作。此外,还介绍了定时器等全局函数的使用方法。

1.全局对象

  • global
    • 类似于客户端 JavaScript 运行环境中的 window
  • process
    • 用于获取当前的 Node 进程信息,一般用于获取环境变量之类的信息
  • console
    • Node 中内置的 console 模块,提供操作控制台的输入输出功能,常见使用方式与客户端类似

—1.1对process的解释
process中一般带有参数信息,默认会有两个参数;

  • process.stdin对象用于接收
  • process.stdout一般用于输出
//接收参数,返回一个参数数组
const stdinArr=process.argv;
stdinArr.forEach(function(item) {
    //输出参数到控制台,
    //console.log最终调用的也是process.stdout.write
    process.stdout.write(item+"\n");
}, this);

这里写图片描述

再一个process接收消息和输出参数的例子

'use strict'
process.stdin.setEncoding("utf8");
process.stdin.on("readable",()=>{
    let chunk=process.stdin.read();
    if(chunk !== null){
        process.stdout.write(`data:${chunk}`);
        if(chunk === 'q'){
            process.exit();
        }
    }
})

这里写图片描述


2.全局函数

  • setInterval(callback, millisecond)
  • clearInterval(timer)
  • setTimeout(callback, millisecond)
  • clearTimeout(timer)

这个不需要解释了,懂javascript的应该都懂

<think>我们正在讨论全局作用域能否使用类的运算符重载(operator)。需要明确的是,类的运算符重载有两种形式:成员函数和非成员函数(通常是友元函数)。在全局作用域中,我们不能直接使用成员运算符,但可以使用非成员运算符。 关键点: 1. 成员运算符函数(operator)是类的成员,因此必须通过类的对象来调用。在全局作用域中,如果没有对象,则不能调用成员运算符。 2. 非成员运算符函数(通常声明为友元)可以像普通函数一样在全局作用域被调用,但必须传入正确的参数。 示例: 假设我们有一个类 `MyClass`,它重载了 `+` 运算符作为成员函数和非成员函数两种情况。 情况1:成员运算符 class MyClass { public: MyClass operator+(const MyClass& other) const; }; 在全局作用域中,如果没有一个MyClass对象,我们就不能调用这个运算符。例如: MyClass a, b; MyClass c = a + b; // 正确,通过对象调用 // 但是,不能直接写 operator+(a, b); 因为成员函数不是这样调用的,实际上成员函数需要对象调用。 情况2:非成员运算符(通常为友元) class MyClass { public: friend MyClass operator+(const MyClass& lhs, const MyClass& rhs); }; 然后在类外定义: MyClass operator+(const MyClass& lhs, const MyClass& rhs) { ... } 这样,在全局作用域中,我们就可以像调用普通函数一样调用它: MyClass a, b; MyClass c = operator+(a, b); // 正确,调用非成员运算符函数 但是,请注意,我们通常使用运算符的中缀形式(a + b),而不是函数调用形式。在全局作用域中,如果我们想直接使用运算符的函数形式,那么非成员运算符是可以的,而成员运算符则不行(因为成员运算符需要对象作为调用者)。 另外,有些运算符必须是成员函数,比如:=, [], (), -> 等。 结论:在全局作用域中,我们可以使用非成员运算符重载(通过函数调用形式),但不能直接使用成员运算符重载(因为缺少调用对象)。 示例代码: */ #include <iostream> using namespace std; class MyClass { int value; public: MyClass(int v = 0) : value(v) {} // 成员运算符重载(二元+,作为成员函数) MyClass operator+(const MyClass& other) const { return MyClass(value + other.value); } // 一元负号运算符(成员函数) MyClass operator-() const { return MyClass(-value); } // 输出运算符通常为非成员,但为了方便演示,我们提供一个打印函数 void print() const { cout << value << endl; } }; // 非成员运算符重载(二元+,作为非成员函数) MyClass operator+(const MyClass& lhs, const MyClass& rhs) { // 注意:这个非成员函数无法访问私有成员,除非声明为友元。这里为了编译,我们假设有公有访问方法,但实际上应该声明友元。 // 为了示例,我们重新设计:假设我们有一个公有成员函数getValue(),但这里没有,所以这个非成员函数无法编译。 // 因此,我们改为友元,并修改类定义: } // 修改后的类,包含友元 class MyClass2 { int value; public: MyClass2(int v = 0) : value(v) {} // 成员运算符 MyClass2 operator+(const MyClass2& other) const { return MyClass2(value + other.value); } // 非成员运算符需要声明为友元 friend MyClass2 operator-(const MyClass2& lhs, const MyClass2& rhs); }; // 非成员运算符:减法 MyClass2 operator-(const MyClass2& lhs, const MyClass2& rhs) { return MyClass2(lhs.value - rhs.value); } int main() { // 在函数作用域内,我们可以通过对象使用运算符 MyClass a(10), b(20); MyClass c = a + b; // 调用成员运算符 // 在全局作用域中(实际上这里在main函数内,但我们可以模拟全局作用域的行为)调用运算符函数 // 错误:不能直接调用成员运算符函数,因为没有对象作为this指针 // MyClass d = operator+(a, b); // 错误:成员运算符函数调用需要对象调用 // 但是,我们可以这样调用成员运算符函数(通过对象调用,但这不是全局作用域的直接调用): MyClass d = a.operator+(b); // 正确,但这实际上是在对象a上调用 // 对于非成员运算符(如MyClass2的减法): MyClass2 e(30), f(10); MyClass2 g = e - f; // 使用中缀 // 在全局作用域中(实际在main函数内)调用非成员运算符函数: MyClass2 h = operator-(e, f); // 正确 return 0; } // 真正的全局作用域(函数外部)不能进行函数调用,所以问题通常出现在函数内部(比如在main函数外,我们无法调用,因为函数调用必须在函数体内)。 /* 因此,严格来说,在全局作用域(即函数体外部)我们不能进行任何函数调用(包括运算符函数)。但是,在函数体内(包括main函数): - 非成员运算符函数可以通过函数调用形式(operator+(a, b))调用。 - 成员运算符函数则必须通过对象调用(a.operator+(b))。 所以,问题的答案取决于“全局作用域”的具体含义: - 如果指函数体外部(如命名空间作用域),则不能使用任何函数调用(包括运算符)。 - 如果指在函数体内但不通过对象(即直接调用),则只能调用非成员运算符函数(通过函数名加参数的方式),成员运算符函数必须通过对象调用。 通常,问题可能关注的是在函数体内是否可以不通过对象而直接调用运算符函数。那么结论是:非成员运算符可以,成员运算符不可以。 补充:在全局作用域(命名空间作用域)中,我们不能写函数调用语句,因为函数调用语句必须出现在函数体内。所以,在全局作用域中,我们只能进行声明和定义,而不能执行代码。 因此,我们通常讨论的是在某个函数体内的情况。 下面,我们总结: 在函数体内: 1. 对于成员运算符重载,只能通过对象调用(例如:obj.operator+(arg) 或使用中缀表达式 obj+arg)。 2. 对于非成员运算符重载,可以直接使用函数调用形式(operator+(arg1, arg2))或者使用中缀表达式。 所以,问题“全局作用域能使用类的operator吗”的答案: - 在全局作用域(命名空间作用域)中,不能执行任何函数调用,包括运算符函数。 - 在函数体内,可以使用非成员运算符函数的函数调用形式,成员运算符函数则需要通过对象调用。 因此,如果要在函数体中像调用普通函数一样调用运算符函数,那么该运算符必须定义为非成员函数。 相关问题: */ </think>### 全局作用域使用类的运算符重载(operator)详解 在 C++ 中,**类的运算符重载(operator)不能在全局作用域直接调用**,但可以通过特定方式使用。以下是详细分析和解决方案: #### 核心问题:运算符重载的作用域限制 1. **成员运算符重载**: - 必须通过类的实例调用 - 隐含 `this` 指针参数 - 示例: ```cpp class Vector { public: Vector operator+(const Vector& other); // 成员重载 }; ``` **全局调用尝试**: ```cpp Vector a, b; ::operator+(a, b); // 错误:成员运算符不能在全局作用域直接调用 ``` 2. **非成员运算符重载**: - 定义在全局或命名空间作用域 - 没有隐含 `this` 指针 - 示例: ```cpp class Vector { // ... }; Vector operator+(const Vector& a, const Vector& b); // 全局重载 ``` **合法调用**: ```cpp Vector a, b; ::operator+(a, b); // 正确:调用全局运算符 ``` #### 正确使用类的运算符的四种方式: ##### 1. 通过类实例调用(最常用) ```cpp class Complex { public: Complex(double r, double i) : real(r), imag(i) {} // 成员运算符重载 Complex operator+(const Complex& other) const { return Complex(real + other.real, imag + other.imag); } private: double real, imag; }; int main() { Complex c1(1.0, 2.0); Complex c2(3.0, 4.0); Complex c3 = c1 + c2; // 通过实例调用运算符 } ``` ##### 2. 显式调用成员运算符 ```cpp int main() { Complex c1(1.0, 2.0); Complex c2(3.0, 4.0); Complex c3 = c1.operator+(c2); // 显式成员调用 } ``` ##### 3. 定义全局运算符函数 ```cpp class Complex { double real, imag; public: Complex(double r, double i) : real(r), imag(i) {} friend Complex operator+(const Complex& a, const Complex& b); }; // 全局运算符重载 Complex operator+(const Complex& a, const Complex& b) { return Complex(a.real + b.real, a.imag + b.imag); } int main() { Complex c1(1.0, 2.0); Complex c2(3.0, 4.0); Complex c3 = ::operator+(c1, c2); // 全局作用域调用 } ``` ##### 4. 通过函数指针间接调用 ```cpp using ComplexOp = Complex (*)(const Complex&, const Complex&); int main() { Complex c1(1.0, 2.0); Complex c2(3.0, 4.0); // 获取成员运算符指针 ComplexOp op = &Complex::operator+; Complex c3 = (c1.*op)(c2); // 通过成员指针调用 // 获取全局运算符指针 ComplexOp global_op = ::operator+; Complex c4 = global_op(c1, c2); // 通过全局函数指针调用 } ``` #### 关键限制说明: 1. **特定运算符必须为成员**: ```cpp class Array { public: // 这些运算符必须定义为成员 int& operator[](size_t index); Array& operator=(const Array&); Array& operator++(); // 前缀++ }; ``` 2. **流运算符必须全局定义**: ```cpp class Logger { friend std::ostream& operator<<(std::ostream&, const Logger&); }; std::ostream& operator<<(std::ostream& os, const Logger& log) { return os << log.message; } ``` 3. **运算符重载限制**: - 不能创建新运算符(如 `operator**`) - 不能改变运算符优先级 - 至少一个参数必须是类类型或枚举 #### 运算符类型总结: | 运算符类型 | 可重载位置 | 全局调用可能性 | |---------------|---------------|--------------| | 成员运算符 | 类内部 | ❌(需通过实例)| | 友元运算符 | 全局/命名空间 | ✅ | | 必需成员运算符 | 类内部 | ❌ | | 必需全局运算符 | 全局/命名空间 | ✅ | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值