using 关键字是 C++11 引入的一项强大特性,它可以用于 类型别名、继承成员 和 别名模板 等不同的场景。在 C++ 中,using 为代码提供了更多的灵活性和可读性。
1. 类型别名(Type Aliases)
using 可以用来创建类型别名,通常与 typedef 功能相似,但语法上更简洁和直观。
1.1 基本类型别名
using IntPtr = int*; // 创建类型别名 IntPtr,等价于 int* 类型
IntPtr p = nullptr; // 使用 IntPtr 作为 int* 类型的别名
- 这里,我们创建了一个 指向整数的指针类型
IntPtr,等价于int*。 - 这种方式比
typedef更具可读性,尤其是在复杂类型的情况下。
1.2 复杂类型别名
using StringMap = std::map<std::string, std::string>;
StringMap myMap; // 使用类型别名 StringMap 来定义一个 std::map
StringMap是对std::map<std::string, std::string>的别名,使得代码更加简洁和易懂。
1.3 函数指针别名
using Callback = void(*)(int); // 定义一个函数指针别名 Callback,指向接收 int 参数并返回 void 的函数
Callback func = print; // 将一个符合签名的函数赋给 func
Callback是一个 函数指针类型,指向 接受int参数并返回void的函数。using使得这段代码更加简洁易懂。
1.4 模板类型别名
template <typename T>
using Vec = std::vector<T>; // 创建模板类型别名 Vec,表示 std::vector<T>
Vec<int> numbers; // 使用 Vec<int> 来定义一个存储整数的向量
- 这里的
Vec是一个模板类型别名,它简化了std::vector<T>的写法,方便代码的书写和维护。
2. 继承成员(继承类成员)
在 C++ 中,类成员(特别是继承自基类的成员)默认是不可访问的,如果你想让派生类访问基类的某些成员,可以使用 using 来显式地继承基类的成员。
2.1 继承构造函数
class Base {
public:
Base(int x) { std::cout << "Base: " << x << std::endl; }
};
class Derived : public Base {
public:
using Base::Base; // 继承基类的构造函数
void print() { std::cout << "Derived class" << std::endl; }
};
int main() {
Derived d(10); // 调用基类的构造函数
d.print();
return 0;
}
- 通过
using Base::Base;,我们显式地 继承了Base类的构造函数,这样在派生类中我们就可以直接调用基类的构造函数了。
2.2 继承基类的成员函数
class Base {
public:
void foo() { std::cout << "Base foo()" << std::endl; }
};
class Derived : public Base {
public:
using Base::foo; // 继承 Base 的 foo 方法
void bar() { std::cout << "Derived bar()" << std::endl; }
};
int main() {
Derived d;
d.foo(); // 调用 Base 类的 foo 方法
d.bar(); // 调用 Derived 类的 bar 方法
return 0;
}
using Base::foo;使得Derived类能够访问Base类的foo()方法。
3. 别名模板(Alias Templates)
using 可以用来为模板定义别名,使模板的使用更加简洁,尤其是对于泛型编程和标准库类型的使用。
3.1 模板别名
template <typename T>
using Ptr = T*; // 为指针类型定义别名
int main() {
Ptr<int> p = nullptr; // 使用 Ptr<int> 作为 int 类型的指针
}
Ptr<T>只是T*的别名,简化了指针类型的定义。
3.2 复杂模板别名
template <typename T>
using Map = std::map<std::string, T>; // 定义一个模板别名,表示以 std::string 为键,T 为值的 map
Map<int> myMap; // 使用 Map<int> 来定义一个键为 std::string,值为 int 的 map
Map<T>是一个模板别名,表示键为std::string,值为T的std::map。
4. using 与 typedef 对比
using 和 typedef 都可以用来定义类型别名,但 using 比 typedef 更简洁且更强大,尤其是在模板类型别名中。
4.1 typedef 的用法
typedef int* IntPtr; // 使用 typedef 创建类型别名 IntPtr,等价于 int* 类型
IntPtr p = nullptr;
4.2 using 的用法
using IntPtr = int*; // 使用 using 创建类型别名 IntPtr,等价于 int* 类型
IntPtr p = nullptr;
using更简洁,且在模板类型别名中表现得更好。
4.3 模板类型别名的对比
typedef:
typedef std::vector<int> IntVector; // 使用 typedef 创建类型别名
using:
using IntVector = std::vector<int>; // 使用 using 创建类型别名
typedef语法较为繁琐,而using使得语法更加简洁。
5. 总结
- 类型别名:
using让我们可以为复杂类型(如函数指针、模板类型等)创建简洁的别名,提高代码的可读性和可维护性。 - 继承成员:
using关键字可以用来继承基类的构造函数或成员函数,使得派生类能够直接使用这些成员。 - 别名模板:
using在模板类型别名方面比typedef更加灵活和简洁,特别是在泛型编程中。 - 与
typedef的对比:using语法简洁,特别适用于模板类型别名,已经成为现代 C++ 中推荐的做法。
通过这些功能,using 能够帮助我们在代码中减少冗余,增加灵活性,尤其在处理复杂类型时,能使代码更加简洁明了。
395

被折叠的 条评论
为什么被折叠?



