聊一聊 C++的特性 explicit && 匿名空间

2,479 阅读4分钟

聊一聊 C++的特性 explicit && 匿名空间

explicit关键字

首先看一下explicit的作用:explicit 是避免构造函数的参数自动转换为类对象的标识符,平时代码中并不是经常用到,但是,有时候就是因为这个,会造成一定的BUG出现,而我们却苦苦查询不到问题;

下面看一个例子来说明下:

案例一

test.cpp

#include <iostream>

using namespace std;

class Test
{
public:
    Test(int a)
    {
        _num = a;
    }
    int getNum()
    {
        return _num;
    }
private:
    int _num;
};

int main()
{
    Test t = 'c';
    cout<<t.getNum()<<endl;
    return 0;
}

我们看下结果:

root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/Lab_tt# g++ test.cpp -o test
root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/Lab_tt# ./test 
99

我们会发现,程序在内部就自动帮我们进行了转换,假设我们本来是想得到是字符‘c’,但是被莫名的修改为了99,其实在一些程序中,我们没有太关注这些自动转换的状态,但是我们阅读一些开源代码库的时候,很多都会避免这类事情发生,而使用关键字explicit就是武器;

来看下构造函数使用explicit的效果:

案例二

#include <iostream>

using namespace std;

class Test
{
public:
    explicit Test(int a)
    {
        _num = a;
    }
    int getNum()
    {
        return _num;
    }
private:
    int _num;
};

int main()
{
    Test t = 'c';
    cout<<t.getNum()<<endl;
    return 0;
}

我们编译一下:

root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/Lab_tt# g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:22:14: error: conversion from ‘char’ to non-scalar type ‘Test’ requested
     Test t = 'c';

我们会发现使用explicit关键字,避免了上面异常自动转换的结果发生;

建议:我们编写C++类的时候,如果能能把握住传参的类型问题,可以忽略这个关键字,不过一般建议 加上,这样,也可以增加代码的健壮性;

匿名命名空间

对于命名空间,相信大家都还是蛮熟悉的,尤其是using namespace std这段,可谓是行云流水呀!这这个使用了std的命名空间;

抛砖引玉法:static

我们可以看一下static,回顾一下: 用于修饰 class 的数据成员,即所谓“静态成员”。这种数据成员的生存期大于 class 的对象(实例/instance)。静态数据成员是每个 class 有一份,普通数据成员是每个 instance 有一份,因此也分别叫做 class variable 和 instance variable。static类成员不像普通的类数据成员,static类数据成员独立于一切类对象处在。static类数据成员是与类关联的,但不与该类定义的对象有任何关系。即static不会像普通类数据成员一样每一个类对象都有一份,全部类对象是共享一个static类成员的。例如A类对象修改了static成员为1,那么B对象对应的static类对象成员的值也会是1。

匿名的空间是C++用于替代使用static定义作用域为本编译单元的全局函数或全局变量的一种新的替代方式,匿名空间与命名的命名空间一样可以嵌套。由于匿名命名空间没有命名空间的名字,所以也无法在其它的编译单元内通过extern声明该变量,于是该变量自然也只在本编译单元内可见

​ ------来源互联网

我们看一下例子;

案例三

#include <iostream>

using namespace std;

namespace 
{
    int num = 10;
}

namespace test
{
    namespace 
    {
        int num = 20;
    }
    void Print()
    {
        cout<<"_________________________"<<endl;
        cout<<"test::Print"<<endl;
        cout<<"test:num:"<<test::num<<endl;
        cout<<"num:"<<::num<<endl;
    }
}

int main()
{
    cout<<"_________________________"<<endl;
    cout<<"test::main"<<endl;
    cout<<"test:num:"<<test::num<<endl;
    cout<<"num:"<<::num<<endl;
    test::Print();
    return 0;
}

结果:

root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/Lab_tt# ./test
_________________________
test::main
test:num:20
num:10
_________________________
test::Print
test:num:20
num:10

相对于static来说,使用匿名空间的好处是: 1.对于一组多个标识符函数只需要使用一个匿名空间来声明,不需要多次输入static。

2.可以嵌套。这样可以在不同命名空间中使用多个同名的标识符。

想了解学习更多C++后台服务器方面的知识,请关注: 微信公众号:====CPP后台服务器开发====