C++ using

本文深入探讨了C++11中using声明的多种用途,包括替代typedef,用于继承构造函数,解决成员函数隐藏问题以及引入别名模板。通过具体代码示例,详细解析了如何在C++11及以后版本中更有效地利用using声明来增强代码的可读性和维护性。

一 C++11前的使用

1 using申明

《c++ primer plus》中:

using申明 : using + 限定名称

限定名称:包含名称空间的名称

举例:

using std::cout;

2 using编译指令

举例:

using namespace std;

using 编译指令可以传递。

二 C++11中的使用

1 取代typedef

举例:

using intvec = std::vector<int>;

2 C++11中增加了继承构造函数,在其中有使用using

3 成员函数隐藏场景中使用

2和3举例:

#include <iostream>
#include <vector>

class A {
 public:
  A() :m_(0) {}
  A(int n) :m_(n) {}
  virtual void show() {
    std::cout << "A show" << std::endl;
  }
  virtual void show(int n) {
    std::cout << "A show int " << n << std::endl;
  }

  void test() {
    std::cout << "A test" << std::endl;
  }
  void test(int n) {
    std::cout << "A show test " << n << std::endl;
  }
  int m_;
};

class AA : public A {
 public:
  using A::A;     // 场景2
  using A::show;  // 场景3
  using A::test;  // 场景3
  virtual void show() {
    std::cout << "AA show" << std::endl;
  }
  void test() {
    std::cout << "AA test" << std::endl;
  }
};

int main() {
  AA aa;
  aa.show();
  aa.test();
  aa.show(1);
  aa.test(1);

  return 0;
}

结果:

《c++ primer plus》中:

如果重新定义派生类中的函数,将不只是使用相同的函数参数列表覆盖基类申明,无论参数列表是否相同,该操作将隐藏所有得同名基类方法。
引出两条经验规则:
第一,如果重新定义继承的方法,应确保与原来的原型完全相同,但如果返回类型是基类引用或者指针,则可以修改为指向派生类的引用或指针,这种特性称为返回类型协变(covariance of return type),因为允许返回类型随类型的变化而变化;
第二,如果基类申明被重载了,则应在派生类中重新定义所有的基类版本。

通俗点讲

即注意隐藏的场景:
如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏。
如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏。

 所以上面代码中场景3两句代码注释掉,AA无法调用带参数的test和show函数。

4 别名模板

举例:

// 别名模板
template<class T>
using ptr = T*; 
// 名称 'ptr<T>' 现在是指向 T 指针的别名
ptr<int> x;

三 参考

using

### C++ 中 `using` 关键字的使用方法 #### 1. 使用 `using` 声明命名空间 在 C++ 编程中,`using` 关键字可以用于声明命名空间中的名称以便于后续代码中直接调用这些名称而无需每次都加上命名空间前缀。这种方式提高了代码可读性和简洁度[^1]。 ```cpp #include <iostream> using namespace std; int main() { cout << "Hello, world!" << endl; } ``` 上述例子展示了如何利用 `using namespace std;` 来简化标准库函数和对象名的访问方式。 #### 2. 使用 `using` 指令与声明的区别 C++ 支持两种形式来引入其他作用域内的名字:一种是 `using` 指令(Using Directive),另一种则是 `using` 声明(Using Declaration)。前者会将整个指定的命名空间或者类的作用域开放给当前文件;后者仅导入特定的名字到局部或全局范围之内[^2]。 - **Using Directive** ```cpp using namespace std; ``` - **Using Declaration** ```cpp using std::cout; using std::endl; ``` 这两种不同的应用可以根据实际需求选择最合适的方案,在某些情况下为了防止污染全局命名空间通常推荐采用具体的 `using` 声明而不是广泛的指令。 #### 3. 类型别名定义 自 C++11 起,`using` 还被用来创建类型别名,这使得复杂类型的表达更加清晰易懂。相比于传统的 typedef 方式来说更为灵活方便[^3]。 ```cpp template<typename T> using ValueType = typename T::value_type; // 等价于之前的 typedef 定义 typedef int* IntPtr; using IntPtr = int*; ``` 这种特性特别适用于模板编程以及处理嵌套类型时能够极大地提升代码维护性并减少错误发生的可能性。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值