namespace/重载/引用

本文详细解析了C++中的命名空间概念及其实现方式,避免了大型项目中可能出现的命名冲突问题。同时介绍了函数重载的使用方法及其背后的原理,以及引用与指针的区别和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(以下遵循markdown语法)


//命名空间问题
using namespace std;//使用标准库命名空间

//函数重载
int add(int i, int j);
int add(int i, int j, int k);//对add函数重载

//指针&引用
int add(int* i ,int* j);//指针
int add(int &i ,int &k);//引用

初学者常对以上语句十分疑惑,整理资料作以下解释:

1. 如何理解命名空间
  • 为什么要设计命名空间

    • 大型工程多开发者时会出现命名冲突
      大型工程常由多个开发者共同编写,在主程序include多个头文件时,多个头文件可能包含名字相同的变量,此时这一组变量处于同一个作用域,产生了命名冲突。

    • 用户自定义的变量名与用户使用的标准库中的名字冲突:如程序员定义函数cout,cout非语言标识符,但在include时,会与标准库命名冲突。

  • 解决方案:引入命名空间,常见用法:

    • using namespace std;

      使用标准库命名空间,此时所有std中出现的命名(如cout)全部指向std中的定义。
      
    • using std::cout;

      使用std中的cout,其它同上
      
    • 在以下条件下:

      
      namespace name1
      {
          int age=18;
      }
      namespace name2
      {
          int age=21;
      }

      我们可以同时

      cout<<name1::age<<endl;
      cout<<name1::age<<endl;

      此外,我们可以同时使用using namespace std& using std::cout,再对部分变量指定命名空间

      //在上述代码基础上
      using namespace name1;
      cout<<age<<endl;//18
      cout<<name1::age<<endl;//18
      cout<<name2::age<<endl;//21
2. 重载(C++为什么支持重载?)
  • 使用方法:

    int add(int i, int j)
    {
        return i+j;
    }
        int add(int i, int j, int k)//对add函数重载
    {
        return i+j+k;
    }

    在主程序中我们可以

    int i, j, k;
    i=j=k=1;
    cout<<add(i,j)<<endl;//2
    cout<<add(i,j,k)<<endl;//3

    对从C语言过来的人来说,这种方法简直不可思议。事实上形参不同时,C++允许同名函数的出现。

  • 为什么C不可以?

    • (知识回顾,可跳过) 易知,从码完代码到运行,编译器需要进行
      • 预处理(包含头文件、注释的删除、标识符与宏的替换)
      • 编译(语法、语义、符号的分析,并对符号进行汇总)
      • 汇编(生成符号表,同时汇编生成二进制代码)
      • 链接(符号表合并、重定位、合并段表)
    • c++对函数名的存储通过添加形参类型的后缀实现对同名函数的区分(重载)

      int add(int i, int j);//存储为_add_int_int
      int add(int i, int j, int k);//存储为_add_int_int_int

      由于C未对函数名的存储作区分,因此C不能出现同名函数。

3. 引用的简析

指针和引用(概念、使用方法、做参数、做返回值的作用,指针和引用的区别)

  • 概念&使用方法:

    我们知道,形参是实参的拷贝,因此在C语言为了改变实参的值我们常使用指针的形式传递参数


    int add(int* i ,int* j);//指针

    C++引入新的语法:引用

    int add(int &i ,int &k);//引用

有别于指针的是:
- 指针变量存储原变量的地址
- 引用是创建原变量的别名,此过程中不创建一个特殊变量去存储地址

引用的出现,可以替代部分原指针的使用,使程序更安全(指针危险)、效率高(减小内存开销),更能解决部分原来指针无法解决的问题,如拷贝构造函数

  • 引用解决的问题实例:
    对如下代码
    class time
    {
        time(time t)//目标为实现一个“拷贝构造函数”
        {
            ······
        }
    }//但事实上形参t的创建又会触发“拷贝构造函数”,最终无限循环,使用引用可解决此问题。

class time
{
    time(time &t)//目标为实现一个“拷贝构造函数”//t只是一个别名,不会创建新的对象
     {
        ······
     }
}

对拷贝构造函数等的解析,详见(预留)

纠正这个代码的错误之处#include <iostream> #include <string> using namespace std; class Fraction { private: int numerator; // 分子 int denominator; // 分母 public: Fraction(int num, int den); // 构造函数 // 重载运算符 Fraction operator+(const Fraction &fra) const; Fraction operator-(const Fraction &fra) const; Fraction operator*(const Fraction &fra) const; Fraction operator/(const Fraction &fra) const; Fraction& operator=(const Fraction &fra); void print() const; // 打印结果 }; // 构造函数 Fraction::Fraction(int num, int den) { // 省略部分代码 } // 重载加法运算符 Fraction Fraction::operator+(const Fraction &fra) const { // 省略部分代码 } // 重载减法运算符 Fraction Fraction::operator-(const Fraction &fra) const { // 省略部分代码 } // 重载乘法运算符 Fraction Fraction::operator*(const Fraction &fra) const { // 省略部分代码 } // 重载除法运算符 Fraction Fraction::operator/(const Fraction &fra) const { // 省略部分代码 } // 重载赋值运算符 Fraction& Fraction::operator=(const Fraction &fra) { // 省略部分代码 } // 打印最简分数或带分数 void Fraction::print() const { // 省略部分代码 } int main() { int x_num, x_den, y_num, y_den; cout << "Input x: "; scanf("%d/%d", &x_num, &x_den); // 格式化输入 cout << "Input y: "; scanf("%d/%d", &y_num, &y_den); // 格式化输入 Fraction x(x_num, x_den); Fraction y(y_num, y_den); Fraction result; // 加法 result = x + y; cout << "x+y="; result.print(); // 减法 result = x - y; cout << "x-y="; result.print(); // 乘法 result = x * y; cout << "x*y="; result.print(); // 除法 result = x / y; cout << "x/y="; result.print(); return 0; }
05-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值