C++ 中的 using 用法有很多种,我们下面剖析下常见几种场景:
-
using 关键字给类型增加别名
-
using 用于继承中的同名函数
-
using 关键字用于构造函数
-
using 关键字给类型增加别名 {#title-0} ==============================
typedef int my_int1;
using my_int2 = int;
void test04()
{
my_int1 a = 100;
my_int2 b = 200;
}
对于普通类型 using 和 typedef 用法很类似,using 主要能力在于模板泛型中定义类型别名,如下代码所示:
//typedef std::vector<int> my_type;
// 如果定义带有模板参数的类型, typedef 无能为力
//template<class T> typedef std::vector<T> my_type; // 报错
template<class T> using my_type = std::vector<T> ; // 正确
所以, using 更加能够适应 C++ 泛型编程的场景。
- using 用于继承中的同名函数 {#title-1} ==============================
当子类和父类的函数重名之后,会自动隐藏父类的同名函数。此时,如果要用父类的函数,就必须增加父类类作用域来访问。使用 using 可以避免隐藏父类的同名函数。
#include <iostream>
using namespace std;
class Base1
{
public:
void show(int)
{
cout << "Base1::show(int)" << endl;
}
void show(int, int) {}
};
class Derived1 : Base1
{
public:
// 父类的函数禁止在子类中隐藏
using Base1::show;
void show() {}
// 使用 using 禁止隐藏父类同名函数
// 假设子类和父类的函数的版本一样(参数个数、参数类型、函数名),此时还是会隐藏父类函数。
void show(int)
{
cout << "Derived1::show(int)" << endl;
}
};
void test05()
{
Derived1 d;
// d.show();
d.show(10);
// d.show(10, 20);
}
- using 关键字用于构造函数 {#title-2} =============================
using 可以继承父类的构造函数,对于子类的成员可以使用就地初始化。
**注意:**父类的构造函数,如果没有默认的话,不会自动继承。
class Base2
{
public:
Base2(int a)
{
m_a = a;
m_b = 0;
}
Base2(int a = 100, int b= 200)
{
cout << "Base2::Base2(int, int)" << endl;
m_a = a;
m_b = b;
}
public:
int m_a;
int m_b;
};
class Derived2 : Base2
{
public:
using Base2::Base2;
/*
Derived2(int a, int b) : Base2(a, b)
{
cout << "Derived2::Derived2(int, int)" << endl;
}
*/
/*
Derived2(int a) : Base2(a) {}
Derived2(int a, int b) : Base2(a, b) {}
*/
public:
int m_c{};
int m_d{};
};
void test06()
{
// 1. 由于C++编译期要求:如果父类没有默认构造,
// 需要初始化列表指定构造函数。所以,子类必须增加构造函数。
// 2. 假设:能够把父类的构造函数继承下来,这样的话,
// 子类就不需要额外去写一些没有意义的构造函数。
// Derived2 d1(10);
Derived2 d2(10, 20);
}