C++ 嵌套类
在C++的面向对象编程中,嵌套类是一个强大而灵活的特性,它允许我们在一个类的内部定义另一个类。嵌套类(也称为内部类)可以帮助我们组织代码结构,增强封装性,并且创建更紧密关联的类层次结构。
什么是嵌套类?
嵌套类是指在另一个类的定义内部声明的类。外部类包含内部类的定义,但它们仍是独立的数据类型。
备注
嵌套类与外部类有特殊的访问关系,但它们的实例是完全独立的对象。
基本语法
嵌套类的基本语法如下:
class OuterClass {
public:
// 外部类的成员和方法
class NestedClass {
public:
// 嵌套类的成员和方法
};
private:
// 外部类的私有成员
};
嵌套类的特性与访问规则
嵌套类具有以下重要特性:
- 作用域:嵌套类的名称在外部类的作用域内可见。
- 访问控制:嵌套类可以访问外部类的类型名称、静态成员和枚举,但不能直接访问外部类的非静态成员。
- 可见性:嵌套类受外部类的访问修饰符控制,决定其对外可见性。
让我们看一个简单的例子:
#include <iostream>
class OuterClass {
public:
static int outerStaticValue;
int outerValue;
class NestedClass {
public:
void display() {
// 可以访问外部类的静态成员
std::cout << "外部类的静态值: " << outerStaticValue << std::endl;
// 但不能直接访问非静态成员
// std::cout << outerValue; // 错误!
}
};
void createNestedObject() {
NestedClass nested;
nested.display();
}
};
// 初始化静态成员
int OuterClass::outerStaticValue = 100;
int main() {
// 创建嵌套类的对象
OuterClass::NestedClass nestedObj;
nestedObj.display();
return 0;
}
输出结果:
外部类的静态值: 100
嵌套类的访问修饰符
嵌套类的可见性受其在外部类中声明所用的访问修饰符控制:
class OuterClass {
public:
class PublicNested {
// 从外部可访问
};
protected:
class ProtectedNested {
// 仅子类可访问
};
private:
class PrivateNested {
// 仅OuterClass可访问
};
};
示例代码展示不同访问级别:
#include <iostream>
class OuterClass {
public:
class PublicNested {
public:
void display() {
std::cout << "这是公有嵌套类" << std::endl;
}
};
private:
class PrivateNested {
public:
void display() {
std::cout << "这是私有嵌套类" << std::endl;
}
};
public:
// 通过外部类访问私有嵌套类
void accessPrivateNested() {
PrivateNested pn;
pn.display();
}
};
int main() {
// 可以直接访问公有嵌套类
OuterClass::PublicNested publicNested;
publicNested.display();
// 不能直接访问私有嵌套类
// OuterClass::PrivateNested privateNested; // 错误!
// 但可以通过外部类提供的方法间接访问
OuterClass outer;
outer.accessPrivateNested();
return 0;
}
输出结果:
这是公有嵌套类
这是私有嵌套类
外部类与嵌套类的交互
虽然嵌套类不能直接访问外部类的非静态成员,但可以通过以下方式实现交互:
- 将外部类对象作为参数传递给嵌套类
- 使用友元关系
- 在外部类中创建和管理嵌套类实例
#include <iostream>
#include <string>
class Person {
private:
std::string name;
int age;
public:
Person(const std::string& n, int a) : name(n), age(a) {}
class Address {
private:
std::string street;
std::string city;
public:
Address(const std::string& s, const std::string& c) : street(s), city(c) {}
void display(const Person& p) {
// 通过引用访问外部类实例
std::cout << p.name << " 住在 " << city << "市 " << street << std::endl;
}
};
// 外部类访问嵌套类
void showAddress(const Address& addr) {
std::cout << name << " 的地址信息:" << std::endl;
addr.display(*this);
}
};
int main() {
Person person("张三", 30);
Person::Address address("和平路123号", "北京");
person.showAddress(address);
return 0;
}
输出结果:
张三 的地址信息:
张三 住在 北京市 和平路123号
嵌套类的实际应用场景
1. 辅助数据结构
当某个类需要特定的辅助数据结构,而这个结构在类外部没有独立意义时,嵌套类是理想选择。
class LinkedList {
private:
// 节点作为嵌套类
class Node {
public:
int data;
Node* next;
Node(int val) : data(val), next(nullptr) {}
};
Node* head;
public:
LinkedList() : head(nullptr) {}
void append(int value) {
Node* newNode = new Node(value);
if (!head) {
head = newNode;
return;
}
Node* current = head;
while (current->next) {
current = current->next;
}
current->next = newNode;
}
void display() {
Node* current = head;
while (current) {
std::cout << current->data << " ";
current = current->next;
}
std::cout << std::endl;
}
~LinkedList() {
Node* current = head;
while (current) {
Node* next = current->next;
delete current;
current = next;
}
}
};
2. 迭代器模式
嵌套类常用于实现迭代器模式:
#include <iostream>
#include <vector>
class Collection {
private:
std::vector<int> data;
public:
// 添加元素
void add(int value) {
data.push_back(value);
}
// 迭代器嵌套类
class Iterator {
private:
const Collection& collection;
size_t index;
public:
Iterator(const Collection& coll) : collection(coll), index(0) {}
bool hasNext() const {
return index < collection.data.size();
}
int next() {
return collection.data[index++];
}
};
// 获取迭代器
Iterator getIterator() const {
return Iterator(*this);
}
};
int main() {
Collection numbers;
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
Collection::Iterator it = numbers.getIterator();
while (it.hasNext()) {
std::cout << it.next() << " ";
}
std::cout << std::endl;
return 0;
}
输出结果:
10 20 30 40
3. 状态模式实现
嵌套类也适合用于状态模式:
#include <iostream>
#include <string>
class Document {
public:
// 文档状态基类 - 嵌套类
class State {
protected:
Document* document;
public:
State(Document* doc) : document(doc) {}
virtual ~State() {}
virtual void view() = 0;
virtual void edit() = 0;
virtual std::string getName() = 0;
};
private:
State* currentState;
std::string content;
// 具体状态 - 草稿状态
class DraftState : public State {
public:
DraftState(Document* doc) : State(doc) {}
void view() override {
std::cout << "查看草稿内容" << std::endl;
}
void edit() override {
std::cout << "编辑草稿内容" << std::endl;
}
std::string getName() override {
return "草稿状态";
}
};
// 具体状态 - 审核状态
class ModeratingState : public State {
public:
ModeratingState(Document* doc) : State(doc) {}
void view() override {
std::cout << "查看审核中的内容" << std::endl;
}
void edit() override {
std::cout << "审核中的文档不可编辑" << std::endl;
}
std::string getName() override {
return "审核状态";
}
};
// 具体状态 - 已发布状态
class PublishedState : public State {
public:
PublishedState(Document* doc) : State(doc) {}
void view() override {
std::cout << "查看已发布的内容" << std::endl;
}
void edit() override {
std::cout << "已发布的文档不可直接编辑" << std::endl;
}
std::string getName() override {
return "已发布状态";
}
};
public:
Document() : content("") {
currentState = new DraftState(this);
}
~Document() {
delete currentState;
}
void setState(State* state) {
delete currentState;
currentState = state;
}
void makeDraft() {
setState(new DraftState(this));
}
void sendForModeration() {
setState(new ModeratingState(this));
}
void publish() {
setState(new PublishedState(this));
}
void view() {
currentState->view();
}
void edit() {
currentState->edit();
}
std::string getStateName() {
return currentState->getName();
}
};
int main() {
Document doc;
std::cout << "当前状态: " << doc.getStateName() << std::endl;
doc.edit(); // 可以编辑
doc.sendForModeration();
std::cout << "