typedef在类模板中的使用

本文探讨了在C++中typedef在类模板中的使用,解释了如何用typedef为模板类创建别名,以简化代码。作者通过示例区分了MyList<iterator<int>>和MyList<int>::iterator两种情况,并指出typedef的一个隐藏功能是将类型声明为类的类型成员,允许通过双冒号操作访问。最后,作者分享了一个无意中发现的问题,即在某些情况下,typedef后的类型可以用作类的成员。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类模板与普通类:

  • 一些需要强调一下的知识:
    在一个类中使用另一个类的公有成员
    能够将另一个类作为返回值类型

同样,普通的类可以做的事模板类也可以做。

#include<iostream>
using namespace std;
struct A {
 int num;
};
class B {
 //这里给类A声明了一个别名。
 //只要位于同样一个作用域中类之间的public数据成员就可以互相访问
 //也可以在这一个类中使用到别的类,不需要额外的声明什么东西。
 typedef A Anything;
private:
 int num;
public:
 B(int x) {
  num = x;
 }
 Anything& Reverse() {
  Anything a_temp;
  a_temp.num = 4*num;
  return a_temp;
 }
};
int main() {
 B b(3);
 A a = b.Reverse();
 cout << a.num << endl;
}

上面代码即显示了使用在类B中使用结构体A的内容。如果为class A那么需要将里面的内容声明为public

typedef的使用:

在模板的最上边使用public声明了一个数据类型表。typedef**仅仅声明了这个模板类的别名,没有把另外一个类当作此类的数据成员。**即不能说类的数据成员是一个类!

即便类不是数据成员,我们依然可以在类模板中使用其他的类。如果在同一个源文件中就可以直接使用,如果是在不同的文件中只需要使用#include指令就可以了。

这里贴出来MyList的数据类型表。

template<typename T>
struct MyList_Node {
 	//没有<T>
	 MyList_Node<T>* prev;
	 MyList_Node<T>* next;
 	T value;
};
template<typename T>
struct MyList_iterator {
	typedef MyList_iterator<T> iterator;
 	typedef MyList_Node<T>* link_type;
 	link_type node;
 	//other codes
 };
 template<typename T>
class MyList {
public:
	 typedef MyList_iterator<T> iterator;
protected:
 	MyList_Node<T>* TailNode;//链表尾指针
	 size_t len;
};

可以看出在10,11,18行都使用了typedef命名了一个别名,并且接收的参数都是模板类类型,原因是这些类型的长度过于长不方便接下来使用,所以说就娶了一个直观易懂的别名。

MyList<iterator<int>>与MyList<int>::iterator

这个东西在我刚接触C++模板的时候是很迷惑的,我迷惑在哪里了呢?我把第二种形式当成了与第一种情况相同。即类模板Mylist<T>的模板参数T接受了一个类类型的泛型。
既然MyList<T>的T接受一个iterator<T>,那么就等价于MyList<T>::iterator
上面的逻辑简直是个神逻辑,自己脑补了下C++有这种神奇的功能。

以上就是这几天迷惑的根源,明白之后才知道自己有多蠢…

MyList<iterator<int>>
MyList<int>::iterator

  • 第一种情况:
    ①说的是泛型MyList<T> 的泛型参数T接受了iterator<int\>参数,即iterator作为一个类类型来实例化MyList类中的成员。
  • 第二种情况:
    ②说的是泛型接受一个int类型,然后::运算符说明MyList<int>类型里面有一个数据类型是iterator(typedef命名的别名,原名是iterator<T>,因为这里MyList的泛型参数为int,所以iterator中的泛型参数也为int。

无意中发现很有意义的问题:

  • [Question]
    为什么对MyList<T>使用::运算符之后可以接着iterator?

可以看出除了typedef外就与iterator没啥关系了,那么我猜测一下可能与::运算符有关!
那么写几行代码来试验一下。

#include<iostream>
class B {
public:
 	 int num;
  	 B() { num = 0; }
};
class Try {
public:
 	 //typedef B Bre;
	 int int_type;
	 double double_type;
private:
 	int pint;
	double pdouble;
};
int main() {
 	Try::Bre a;
 	std::cout << a.num;
}
  • 没有第九行的时候,在Try后键入::运算符代码提示如下,说明此时我们可以使用的是Try类中的两个public类型数据成员。
    在这里插入图片描述
  • 而有第九行的时候,在Try后键入::运算符代码提示如下,说明此时我们不仅可以使用的是Try类中的两个public类型数据成员,**更可以使用使用typedef引入的·class Bde的别名Bre,可见typedef还有一个功能就是把一个类型声明为类的类型成员,这时候就可以使用通过双冒号时使用这些类型成员了。
    在这里插入图片描述

那么在这种情况下,在MyList中使用
typedef MyList_iterator<T> iterator;
语句即可完成将iterator类型声明为MyList中的类型成员,也即可以通过
MY=yList<T\>::iterator iter来定义一个MyList_iterator<T>的变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值