C++中using的三种用法举例详解

1. using声明(引入单个名称)

using声明是将命名空间中某个名字单独引入到当前作用域。这使得我们在当前作用域下可以直接使用该名字而无需使用作用域限定符::

using std::string;
string s = "123";

using声明可以改变派生类对父类成员的访问控制。

class Base{
protected:
    int bn1;
    int bn2;
};
 
class Derived: private Base{    //私有继承
public:
    using Base::bn1;    //在当前作用域中引入了父类的保护成员, 在当前作用域中可以访问
};
 
class DerivedAgain: public Derived{     //在Derived的子类中仍然可以访问bn1
};
 
int main(){
    Derived d;
    DerivedAgain da; 
    d.bn1 = 1;
    d.bn2 = 2;   //error, 'bn2' is a private member of 'Base'
    da.bn1 = 3;  //ok
    std::cout<<d.bn1<<std::endl;
    return 0;
}

尽管Derived是Base的私有继承,但是通过using声明父类的成员,我们就可以在Derived类以及其后续派生类中使用了。

2. using指示(引入命名空间)

using指示就是将一个命名空间中的所有名字全部引入到当前作用域(将命名空间在当前作用域展开)。可能会存在命名冲突的问题。

using namespace std;      //我们常用的std命名空间展开

3. 类型重定义(替代typedef)

语法:

using alias = typename;//使用别名去替代原始类型(重命名)

在C++11中,我们可以使用这样的语法来替代typedef的功能了。

using ULL = unsigned long long;           //typedef unsigned long long ULL;
using func = void(*)(int, int);         //typedef void(*func)(int, int);

在Effective Modern C++中的条款9说明了, 使用using替代typedef

typedef存在一些限制。

当我们想实现一个这样的模板: 将一个int映射到任意类型的模板。类似于下面的功能:

typedef std::map<int, int> mapIntInt;
typedef std::map<int, bool> mapIntBool;
typedef std::map<int, std::string> mapIntString;
//...

在C++98/03中,我们必须这样写才能实现:

template <class Val>
struct mapInt{
    typedef std::map<int, Val> type;
};

int main(){
    mapInt<int>::type imap;               //将int映射到int的
    mapInt<bool>::type bmap;      //将int映射到bool的
    mapInt<std::string>::type smap;       //将int映射到string的
    return 0;
}

在C++11中,我们可以直接使用using重定义模板

template <class Val>
using mapInt = std::map<int, Val>;

int main(){
    mapInt<int> imap;
    mapInt<bool> bmap;
    mapInt<std::string> smap;
    return 0;
}

总结

原文地址:https://blog.csdn.net/weixin_51696091/article/details/127976813