C++ 基础3
typedef
为现有类型创建一个新名字
主要有以下几种形式:
- 为基本数据类型定义别名
- 为指针定义别名
- 为自定义数据类型定义别名
- 为数组定义别名
- 声明函数
定义新名称为了简化一些复杂的数据类型,以方便使用
为基本数据类型定义名称
语法typedef 旧类型 新名字
例如:
typedef int I;
int main()
{
I i = 10; //等同于 int i=10;
}
为指针定义名称
typedef int* I_P;
int main()
{
int a = 10;
I_P a_p= &a; //等同于int *a_p = &a;
}
还有一个在刚开始学c++容易犯的错误,如下代码其实是定义了一个int指针类型
的a 一个int类型
的b
int main()
{
int* a, b;
}
可以用typedef来解决这种问题,如下,这样就是定义两个int指针类型的变量了
typedef int* I_P;
int main()
{
I_P a,b;
}
为自定义数据类型定义名称
在一些旧的c代码中,使用结构体必须带上struct关键字,如下
struct User {
int age;
string name;
};
int main()
{
struct User user = { 1,"" };
}
可以使用typedef来定义为User,这样就不用再写struct关键字了
typedef struct User {
int age;
string name;
};
int main()
{
User user = { 1,"" };
}
还有另一种方式来定义-把结构体名称放到后面,这两者是一样的
typedef struct {
int age;
string name;
} User;
int main()
{
User user = { 1,"" };
}
结构体和typedef组合容易搞错的地方
例1:
typedef struct {
int age;
string name;
} u;
struct People {
int age;
string name;
} p;
int main() {
u u1;
u1.age;
p.age;
}
请注意,以上代码u是别名,而p是变量! 当结构体前面存在typedef的时候,结尾}后面的是别名
例2:
以下代码声明了一个Node结构体,现在我们使用Node或np都可以来创建对象
typedef struct Node{
Node* prev;
} np;
int main()
{
Node n;
n.prev;
np n2;
n2.prev;
}
但是当我们修改代码如下后
typedef struct Node {
Node* prev;
} *np;
是不是有点蒙,其实分为两步
第一步创建一个Node结构体
struct Node {
Node* prev;
}
第二步给这个Node指针声明别名
typedef Node* np;
也就是说如下两个代码效果是一样的
struct Node {
Node* prev;
} ;
typedef Node* np;
typedef struct Node {
Node* prev;
} *np;
那我们能不能使用np来代替Node结构体中的Node*呢?类似这样
typedef struct Node {
np prev;
} *np;
结果不可以,原因其实刚刚说过,因为它是先定义的Node结构体,再去声明的np别名,
在定义Node结构体的时候np别名并不存在,所以编译不通过
为数组定义名称
typedef int INT_ARRAY_10[10];
int main()
{
INT_ARRAY_10 a; //等同于 int a[10]
a[0] = 1;
}
声明函数
typedef int F();
定义了一个返回值为int 无参的函数
typedef char* T(double* d);
定义了一个返回为char* ,形参为double* d的函数
typedef int F();
typedef char* T(double* d);
class User {
public:
F(add);
T(update);
};
char* User::update(double* d) {
return new char('2');
}
int User::add() {
cout << "add!";
return 100;
}
int main(){
User u;
u.add();
double a = 3.45;
u.update(&a);
}
typedef模板
typedef没有办法直接使用模板,只能在外层套一个struct
template <typename T>
struct Vec {
typedef vector<T> v;
};
int main() {
Vec<int>::v v1;
v1.push_back(10);
}
typedef是为类型添加一个新的名称,并没有创建一个类型
typedef和#define的区别
#define
是预处理指令,在编译预处理时进行字符替换,并不会做任何额外的处理
而typedef是在编译时处理的,在自己的作用域内给一个已经存在的类型一个别名
using
命名空间声明
例如最常见的输出cout
#include <iostream>
using namespace std;
int main()
{
cout;
}
如果没有引入的话就需要单独指定
#include <iostream>
int main()
{
std::cout;
}
修改父类访问权限
class Animal {
protected:
int a;
int b;
void e() {
}
void f() {
}
};
class Cat : public Animal{
};
int main()
{
Cat c;
c.a; //报错,没有权限访问-以下都是这个错误
c.b;
c.e();
c.f();
}
如上的代码因为Animal使用的是protected权限,只能子类内部访问,这时我们可以使用using来修改权限
class Animal {
protected:
int a;
int b;
void e() {
}
void f() {
}
};
class Cat : public Animal{
public:
//在当前域引入父类的保护成员,使在类外依然可以访问到
using Animal::a;
//引入函数
using Animal::e;
};
int main()
{
Cat c;
c.a; //正常
c.b; //报错-没有权限
c.e(); //正常
c.f(); //报错-没有权限
}
类型重定义
语法using 别名=原类型
using ui = unsigned int;
int main()
{
ui i = 100;
}
和typedef类似,以下代码中两者是等价的