前言

嵌套反正不是第一次用了,嵌套类还算陌生,毕竟友元不算。
要说稍微接近一点的也是命名空间,但总归不是一个东西。


正文

设计一个角色:

  1. 生命值
  2. 内力值
  3. 武器
    1. 强化等级
    2. 品阶

可能第一印象是用struct结构体,当然也没毛病,因为类用的少,得心应手还是结构体,不过反正要慢慢过渡。


定义嵌套类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once
class Hack{
public:
int hp;
int mp;
class weapon{
short lv;
enum weaponLv{
normal = 0,
high,
rare,
myth
};
};
};

嵌套写法在结构层次上感知会更强,前提是里面的类不需要给别的类用,毕竟嵌套在里面作用域也就在里面了。

调用嵌套类就要用::表明作用域。
比如这里的Hack::weapon lv;

注:嵌套类的作用域也受封装属性管辖,即private封装的结构体无法被外部调用。


既然已经学了文件分级写,那么.h就应该都是声明,定义都放在.cpp里面

这里要改动的就是嵌套的类,当然要注意嵌套类的作用域问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Hack.h
#pragma once
enum class WeaponLv{
normal = 0,
high,
rare,
myth
};

class Hack{
public:
int hp;
int mp;
class Weapon;
};

Hack.h这样写没问题。

但是.cpp要注意

1
2
3
4
5
6
7
8
9
10
#include "Hack.h"
class weapon{
short lv;
enum weaponLv{
normal = 0,
high,
rare,
myth
};
};

这样写是定义新的类,跟嵌套没关系了,要加上作用域,至于类的作用域写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<iostream>
#include"Hack.h"

class Hack::Weapon{
public:
Weapon();

short lv;
WeaponLv wlv;

~Weapon();
};

Hack::Weapon::Weapon(){
this->lv = 0;
std::cout << "构造函数" << std::endl;
}
Hack::Weapon::~Weapon(){
std::cout << "析构函数" << std::endl;
}

int main(){
Hack::Weapon hw;

return 0;
}

可以看到能够实例化一个嵌套类,因为我们设置了构造和析构时打印。

ps:当时想把定义放在Hack.cpp的,但是由于跨文件,编译成.obj的时候会重复定义就很烦
手动写成内联又有点多此一举。


然后是嵌套类指针的问题

1
2
3
4
5
6
7
8
9
10
class Hack::Weapon{
public:
Weapon();

Weapon *returnW();
short lv;
WeaponLv wlv;

~Weapon();
};

如果说写成这样

1
2
3
Weapon* Hack::Weapon::returnW(){
return this;
}

是行不通的,因为这个类是嵌套的,无法直接调用这个类型,所以指针的时候也要写上作用域:

1
2
3
Hack::Weapon* Hack::Weapon::returnW(){
return this;
}

这样就ok了。就是感觉套多了看着也恶心不习惯。

所以说嫌麻烦就塞到头文件得了


访问权限

  1. 嵌套类可以访问外层类的所有静态成员
  2. 外层类仅能访问嵌套类的公有成员
1
2
3
4
5
6
7
8
9
10
11
class Hack{
public:
int hp;
int mp;
class Weapon;

static void test(){

}
static int hh;
};

可以看到静态的成员变量和函数都能够访问不报错。

但是像常规的就无法访问了,因为常规的涉及到内存分配,它不是提前就分配好的。

即便静态的成员变量和函数处在private下,嵌套类依旧能访问

换过来,外层类对嵌套类的访问权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Hack::Weapon{
public:
Weapon();

Weapon *returnW();
short lv;
WeaponLv wlv;
static void test1(){

}

~Weapon();
private:
int x;
};

目前嵌套类里面有这么多成员

可以看到它除了私有的x无法调用,其他都能调用。


局部类

定义在函数类的内被称为局部类

  1. 局部类的定义必须写在类中
  2. 局部类中不允许使用静态成员变量
  3. 局部类可以访问全局变量

因为函数出栈就释放了。。。所以尽量避免把类写在函数里。
不能使用静态成员也是这个道理,函数出栈就没了,这个静态的就成了僵尸内存了。。至于静态成员函数有争议,但是我认为也是不能用,都是一个道理的,提前划分了,但是函数是出栈就释放,变量和函数都成了无人认领的。

最后能访问全局这个无伤大雅,毕竟全局是大哥啊,不能访问还叫什么全局。


结语

写多了记得注释。。不如阅读起来都恶心