迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

在 C++ 中 using 与 typedef

作者:迹忆客 最近更新:2023/08/19 浏览次数:

本文试图区分 typedef 和 using。 在 C++ 函数式编程中,这些关键字具有相同的目的和语义,它们之间的差异非常小。

本文将解释不同上下文中的关键字,以确保读者理解这些关键字的作用以及 typedef 和 using 之间的区别。


C++ 中的 using 关键字

了解 using 关键字与 typedef 的对比对于了解 typedef 和 using 之间的差异非常重要。

它用于将对象带到程序的当前范围。 这意味着它可以用作从 C++ 引入说明符的访问工具。

让我们看一个例子。

#include <iostream>

int main() {

using std::cout;
using std::string;

int a = 56;
cout << a;
return 0;
}

输出:

56

在这里,关键字 using 用于从命名空间访问 cout 和 string 等说明符,并将它们带入程序的范围内。

类似地,using 也可以用于访问其他说明符,或者通过 using - using namespace as std 来引入整个命名空间。 这将整个命名空间置于程序的作用域内,并且每个说明符都可以使用 std 进行访问。

using 关键字的示例

下面的代码片段创建了一个 Parent 类,其公共方法 add 有两个整数变量 a 和 b 作为参数。 add 方法打印两个变量的总和。

子类以保护模式派生父类,这意味着父类的所有成员都将作为受保护成员继承。

在 main 函数内部,使用 Child 类创建对象的实例,并使用该对象派生方法 add。

#include <iostream>
using namespace std;
class Parent {
public:
    void add(int a,int b) {
        cout << "Result = " << a+b << endl;
    }
};
class Child : protected Parent {
    public:
        using Parent::add;
};
int main() {
    Child obj;
    obj.add(15,30);
    return 0;
}

输出:

Result = 45

这里,关键字using用于通过子类访问父类的add方法。

在 C++ 中使用 using 关键字实现循环

这里的语法通过using来实现for循环。

for (using i = int; i{} != 0;) {
    i++;
}

在基于范围的循环的情况下,使用如下:

std::vector<int> v{1, 2, 3};
for (using Foo = int; Foo f : v) {
    (void)f;
}

在 C++ 中使用 using 关键字 switch Case 语句

在 switch case 语句中,using 的实现如下:

if (using Foo = int; true) {
    (void)Foo{};
}
switch (using Foo = int; 0) {
    case 0: (void)Foo{};
}

C++ 中的 typedef 关键字

关键字 typedef 具有使用自定义名称命名类型的功能。 这意味着可以为现有数据类型引入别名。

在本节中可以观察到 typedef 和 using 之间的主要区别。

下面的程序清楚地解释了这个概念。

#include <stdio.h>
#include <string.h>

typedef struct Books {
   char title[50];
   char author[50];
   char subject[100];
   int book_id;
} Book;

引入了一个结构体类Book,它有四个变量。 使用 typedef 将这四个变量构造为新的数据类型,并且该类型的名称为 Book。

在主类内部,必须创建一个新对象来访问 Book 类型并获取其变量(根据要求)。

可以看出,各个变量是使用语法 object_name.variable_name,"input" 来调用的。 一旦给这些变量提供了数据,就会使用与调用它相同的方法来打印它。

int main( ) {

   Book book;

   strcpy( book.title, "Typedef vs using");
   strcpy( book.author, "JS");
   strcpy( book.subject, "C Programming");
   book.book_id = 6495407;

   printf( "Book title : %s\n", book.title);
   printf( "Book author : %s\n", book.author);
   printf( "Book subject : %s\n", book.subject);
   printf( "Book book_id : %d\n", book.book_id);

   return 0;
}

输出:

Book title : Typedef vs using
Book author : JS
Book subject : C Programming
Book book_id : 6495407

在 C++ 中使用 typedef 关键字进行循环

在循环迭代期间,使用 (typedef (datatype)Function; Function{} != 0;) 语法定义 typedef。

for (typedef int i; i{} != 0;) {
    i++;
}

在基于范围的循环迭代期间,typedef 用作:

std::vector<int> v{1, 2, 3};
for (typedef int Foo; Foo f : v)
//   ^^^^^^^^^^^^^^^ init-statement
{
    (void)f;
}

二维矩阵内基于范围的循环的另一个示例:

for (typedef struct { int x; int y;} P; auto [x, y] : {P{1, 1}, {1, 2}, {3, 5}})
{
    (void)x;
    (void)y;
}

在 C++ 中使用 typedef 关键字 Switch Case 语句

typedef 关键字用于 switch case 语句中,如下所示。

if (typedef int Foo; true)
{
    (void)Foo{};
}

switch (typedef int Foo; 0)
{
    case 0: (void)Foo{};
}

typedef 的使用以及在定义模板中的使用

我们从函数式编程的上下文中观察到了 typedef 和 using 之间的差异。 需要理解的另一个重要部分是如何定义模板。

在C++中,typedef具有为模板定义别名的功能。 它已经使用了很长时间,但据观察,typedef 的语义与模板不太匹配。

为了解决这个问题,typedef 已被弃用,并已开始使用。

在下面的示例中,在定义模板的上下文中讨论了 typedef 和 using 之间的差异。

C++ 中使用 typedef 的别名模板

示例1:

这里,矩形被定义为具有 x 长度和静态宽度,需要使用模板为其指定别名。

<size_t N> 是存储矩形长度的模板。 相反,Dimension 是一个使用 typedef 为其指定别名 Rectangle 的对象。

这里,代码将 Rectangle 指定为 Dimension<N,1> 的别名,这意味着 Dimension 对象将具有长度和宽度。 这里,对象 Dimension 的长度 <size_t N> 和宽度为 1。

template <size_t N>
struct Rectangle
{
    typedef Dimension<N, 1> type;
};

这意味着程序员需要将单个值参数 size_t N 传递给 Rectangle。 编译器会将传递的数据作为长度,而宽度设置为 1。

语法 Rectangle<5>::int 将整数值 5 传递给对象 Dimension,它与编写 Dimension<5,1> 相同。

由于 typedef 已被弃用,上述示例在最近的 C++ 版本中不再使用。 使用 using 为模板指定别名比上面的示例更简单。

示例2:

模板类 Match 在下面的代码片段中定义。 这个 Match 类被赋予一个别名模板 MatchBox。

Match 类将来也可以被替换。

template <typename U> struct Match {};

template <typename U> struct MatchBox
{
    typedef Match<U> type;
};

MatchBox<int>::type variable;

template <typename V> struct bar { typename MatchBox<V>::type_var_member; }

如果需要类型抽象,但还需要保留模板参数以便将来提供,那么就应该编写这种代码。

在 C++ 中使用关键字给模板起别名

示例1:

本节介绍了 typedef 和在模板上下文中使用之间的区别。 这里,模板 <size_t N>与typedef示例1中使用的相同,它存储矩形的长度。

不使用 struct,而是通过关键字 using 将别名 Rectangle 分配给对象 Dimension。 这与分配操作员的方式相同。

分配别名后的别名矩形的长度和宽度分别为 N 和 1。

template <size_t N>
using Rectangle = Dimension<N, 1>;

可以看出,using 提供了更精致的别名版本,更容易编写和实现。 这里使用的语法的可读性似乎有所提高,因为它现在更像是变量和运算符的常规赋值。

示例2:

此示例使模板参数保持打开状态,以便仍然可以指定它。 在 typedef 示例中,此过程需要多行代码。 但是 using 语法减少了代码和复杂性。

template <typename U> using MatchBox = Match<U

MatchBox<int> variable;
template <typename V> struct bar { MatchBox<V> _var_member; }

使用 using 关键字为模板定义别名比 typedef 容易得多,因为该过程类似于变量的复制赋值。


总结

本文介绍了 C++ 中关键字 typedefusing 之间的区别。 读者将了解这些关键字的基本差异以及在不同编程环境中的实现。

希望本文对您的学习之旅有所帮助。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

使用 C++ 编程 Arduino

发布时间:2024/03/13 浏览次数:127 分类:C++

本教程将讨论使用 Arduino IDE 在 C++ 中对 Arduino 进行编程。

如何在 C++ 中实现毫秒级的睡眠

发布时间:2024/01/02 浏览次数:230 分类:C++

本文介绍了在 C++ 中使用不同方法暂停程序执行,实现睡眠的方法。本文介绍了在 C++ 中睡眠毫秒的方法。使用 std::this_thread::sleep_for 方法在 C++ 中睡眠

如何在 C++ 中将双精度数四舍五入到整数上

发布时间:2024/01/02 浏览次数:151 分类:C++

本文演示了如何在 C++ 中把双精度数四舍五入到整数中。本文将为大家讲解几种在 C++ 中如何将双精度数四舍五入为整数的方法。使用 round() 函数将双精度数四舍五入到整数

如何在 C++ 中以毫秒为单位获取时间

发布时间:2024/01/02 浏览次数:142 分类:C++

本文介绍了如何在 C++ 中获取以毫秒为单位的时间。本文将介绍多种 C++ 方法,介绍如何以毫秒为单位获取时间。

如何在 C++ 中把 Char 数组转换为 Int

发布时间:2024/01/02 浏览次数:143 分类:C++

本文演示了在 C++ 中把 char 数组转换为 int 类型的方法。本文将介绍将 char 数组转换为 int 类型的 C++ 方法。使用 std::strtol 函数将 char 数组转换为 int 类型

如何在 C++ 中将 ASCII 码转换为字符

发布时间:2024/01/02 浏览次数:520 分类:C++

本文介绍了在 C++ 中如何将 ASCII 值转换为 char 的方法。本文将演示关于如何在 C++ 中把 ASCII 值转换为字符的多种方法。在 C++ 中使用赋值运算符将 ASCII 值转换为字符

如何在 C++ 中把十进制转换为二进制

发布时间:2024/01/02 浏览次数:239 分类:C++

本文介绍如何在 C++ 中把十进制数转换成二进制数。本文将介绍几种在 C++ 中如何将十进制数转换为二进制表示的方法。在 C++ 中使用自定义定义的函数将十进制数转换为二进制数

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便