C++梁哥笔记day1 | 我的日常分享

C++梁哥笔记day1

C++对C的拓展

::作用域运算符

通常情况下,如果有两个同名变量,一个是全局变量,一个是局部变量,那么局部变量在其作用域内具有较高的优先权,它将屏蔽全局变量。

1
2
3
4
5
6
7
int a = 10;
void test1(){
//局部变量
int a = 20;
//打印出的是局部变量
cout<< "a:" << a << endl;
}

运行结果:
图片
::作用域运算符可以解决上面局部变量与全局变量重名的问题

1
2
3
4
5
6
7
8
9
int a = 10;
void test2(){
//局部变量
int a = 20;
//打印局部变量
cout<< "a:" << a << endl;
//打印全局变量
cout<< "a:" << ::a << endl;
}

运行结果:
图片

C++命名空间(namespace)

命名空间的定义和使用

  1. 创建一个命名空间
    1
    2
    3
    4
    5
    6
    7
    //定义一个名字为A的命名空间(里面可以是变量、函数)
    namespace A{

    }
    namespace B{

    }

    注意:只能在全局范围内定义,不能再局部范围内定义

  2. 使用命名空间的内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    namespace A{
    int a = 10;
    }
    namespace B{
    int a = 20;
    }
    void test3(){
    //报错 a未定义
    //cout << "a:" << a << endl;
    //使用A空间中的a
    cout << "a:" << A::a << endl;
    //使用B空间中的a
    cout << "a:" << B::a << endl;

    }
    运行结果:
    图片

命名空间的特点详解

  1. 命名空间只能在全局范围内定义
    错误写法

    1
    2
    3
    4
    5
    6
    7
    8
    void test4(){
    namespace A{
    int a = 10;
    }
    namespace B{
    int a = 20;
    }
    }

    结果:
    图片

  2. 命名空间可以嵌套

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace A{
    int a = 1000;
    namespace B{
    int a=2000;
    }
    }
    void test5(){
    cout<<"A中的a:"<<A::a<<endl;
    cout<<"B中的a:"<<A::B::a<<endl;
    }

    运行结果:
    图片

  3. 命名空间是开放的,可以随时把新的成员加入已有的命名空间中(常用)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    namespace A{
    int a = 100;
    }
    //中间写了很多代码
    namespace A{
    int b = 200;
    }
    void test6(){
    cout<<"A中的a:"<<A::a<<endl;
    cout<<"A中的b:"<<A::b<<endl;
    }

    运行结果:
    图片

  4. 命名空间可以存放变量和函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    namespace A{
    int a=10;//变量
    void func(){//函数
    // cout<<"A中的a:"<<A::a<<endl;
    cout<<"A中的a:"<<a<<endl;
    /*
    这个时候的a可以不加作用域A::
    函数和a都在命名空间内,
    加这个有点好像一家人不是一家人一样的
    */
    }
    }
    void test7(){
    A::func();
    }

    运行结果:
    图片

  1. 命名空间中的函数,可以在命名空间外面定义
    内部声明
    外面定义
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    namespace A{
    int a=100;
    void func();
    }
    void A::func(){//成员函数 在外部定义时,记得要加作用域
    //cout << "a:" << A::a << endl;
    //访问命名空间的数据可以不用加作用域
    cout << "a:" << a << endl;
    }
    void test8(){
    A::func();
    }
    运行结果:
    图片

无名命名空间

意味着命名空间中的标识符只能在本文件内访问,相当于给这个标识符加上了static,使得其可以作为内部连接

1
2
3
4
5
6
7
8
9
10
namespace{
int a = 100;
void func(){
cout << "hello namespace" << endl;
}
}
test9(){
cout << "a:" << a << endl;
func();
}

运行结果:
图片

命名空间的别名

1
2
3
4
5
6
7
8
9
10
11
12
13
namespace veryLongName{
int a = 100;
void func(){
cout << "hello namespace" << endl;
}
}
void test10(){
//取别名
namespace shortName = veryLongName;
cout<<"veryLongNmae::a"<<shortName::a<<endl;
veryLongName::func();
shortName::func();
}

运行结果:
图片

using 声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace veryLongName{
int a = 200;
void func(){
cout << "a:" << a << endl;
}
}

void test11(){
//使用命名空间
using namespace veryLongName;

//出现的变量 先从veryLongName命名空间中找 找不到再从其他地方去找
cout<<"a:"<<a<<endl;
func();
}

运行结果:
图片

  • 优点:简化了代码

  • 缺点:容易冲突,当名字重名的可能会出现问题

  • using 指明使用具体的命名空间成员(了解)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    namespace veryLongName{
    int a = 200;
    void func(){
    cout << "a:" << a << endl;
    }
    }
    void test12(){
    //使用指定命名空间
    using veryLongName::a;

    //指定了a 可以使用命名空间中的a
    cout<<"a:"<<a<<endl;

    //没有指定func() 会报错
    //func();
    veryLongName::func();
    }

    运行结果:
    图片

注意:不同命名空间中的同名成员使用的时候注意二义性。

using声明碰到函数重载

  • 函数重载
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void func(){
    cout<<"无参函数"<<endl;
    }
    void func(int a){
    cout<<"一个参数"<<endl;
    }
    void func(int a,int b){
    cout<<"两个参数"<<endl;
    }
    test13(){
    func();//你不传参数 调用的是第一个函数
    func(1);//传一个参数 调用的是第二个函数
    func(1,1);//传两个参数 调用的是第三个函数
    }
    运行结果:
    图片

函数重载,c++中函数名+参数组合代表的是函数的入口地址,它在内部做了重新载入,类似func()变成func_void(),func(int a)变成func_int,func(int a,int b)变成func_int_int。在C语言中这样写是会报错的,C语言中函数名就是函数的入口地址。

  • 当函数重载放在命名空间里面时
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    namespace A{
    void func(){
    cout<<"无参函数"<<endl;
    }
    void func(int a){
    cout<<"一个参数"<<endl;
    }
    void func(int a,int b){
    cout<<"两个参数"<<endl;
    }
    }
    void test14(){
    //using指明使用A中的func 会对所有的func起作用
    using A::func;
    func();
    func(1);
    func(1,1);
    }
    运行结果:
    图片

std详解

using namespace std;
cout cin end 都是std中的成员

1
2
3
4
5
6
7
#include<iostream>
using namespace std;
int main(){
std::cout<<"hello"<<std::endl;
cout<<"hello"<<endl;
reutrn 0;
}

运行结果:
图片

总结:

1、 命名空间的定义(不能在函数内定义命名空间)
2、使用命名空间的成员,最安全的方式是 命名空间名::成员名
3、using namespace 命名空间名 使用整个命名空间 (重要)
4、单独使用命名空间中的具体成员:using 命名空间名::成员名