C++类层次结构与访问控制详解
立即解锁
发布时间: 2025-08-22 00:46:17 阅读量: 2 订阅数: 12 


C++编程语言第三版:全面解析与实践
# C++ 类层次结构与访问控制详解
## 1. 类层次结构基础
在 C++ 编程中,类层次结构是一个重要的概念。例如有如下类的声明:
```cpp
Window { set_color(), prompt() }
Window_with_border { set_color() }
Window_with_menu { prompt() }
My_window { prompt() }
```
这里展示了不同类型的窗口类,它们之间存在着一定的层次关系。
### 1.1 类层次结构的错误情况
如果两个类重写了基类的函数,但彼此之间没有重写关系,那么类层次结构就会出现错误。因为无法构建虚函数表,对完整对象调用该函数会产生歧义。例如,若某个类没有声明 `write()` 函数,而其派生类中对 `write()` 函数的声明可能会在定义该类时导致错误。解决这种冲突的方法是在最派生的类中添加重写函数。
### 1.2 混合类(Mixin)
提供虚基类部分(而非全部)实现的类通常被称为“混合类”。
## 2. 访问控制
在 C++ 中,类的成员可以被声明为 `private`、`protected` 或 `public`,这反映了访问类的三种函数类型:实现类的函数(其友元和成员)、实现派生类的函数(派生类的友元和成员)以及其他函数。
### 2.1 访问控制规则
| 访问修饰符 | 使用范围 |
| ---- | ---- |
| `private` | 只能被声明该成员的类的成员函数和友元使用 |
| `protected` | 可以被声明该成员的类的成员函数和友元,以及派生类的成员函数和友元使用 |
| `public` | 可以被任何函数使用 |
### 2.2 访问控制示例
以下是一个模板列表类的示例,展示了如何使用访问控制:
```cpp
template<class T> class List {
private:
struct Link { T val; Link* next; };
struct Chunk {
enum { chunk_size = 15 };
Link v[chunk_size] ;
Chunk* next;
};
class Underflow { };
Chunk* allocated;
Link* free;
Link* get_free();
Link* head;
public:
void insert(T);
T get();
// ...
};
template<class T> void List<T>::insert(T val)
{
Link* lnk = get_free();
lnk->val = val;
lnk->next = head;
head = lnk;
}
template<class T> List<T>::Link* List<T>::get_free()
{
if (free == 0) {
// allocate a new chunk and place its Links on the free list
}
Link* p = free;
free = free->next;
return p;
}
template<class T> T List<T>::get()
{
if (head == 0) throw Underflow();
Link* p= head;
head = p->next;
p->next = free;
free = p;
return p->val;
}
```
在这个示例中,`Link`、`Chunk` 等结构体和类被声明为 `private`,只有类的成员函数可以访问它们。而非成员函数(除友元外)没有这样的访问权限,例如:
```cpp
void would_be_meddler(List<T>* p)
{
List<T>::Link* q = 0;
// error: List<T>::Link is private
// ...
q = p->free;
// error: List<T>::free is private
// ...
if (List<T>::Chunk::chunk_size > 31) {
// error: List<T>::Chunk::chunk_size is private
// ...
}
}
```
### 2.3 默认访问权限
在 `class` 中,成员默认是 `private` 的;在 `struct` 中,成员默认是 `public` 的。
## 3. 受保护成员
### 3.1 受保护成员的使用示例
以 `Window` 类为例,`own_draw()` 函数是为派生类设计的构建块,不适合一般使用;而 `draw()` 操作则是为一
0
0
复制全文
相关推荐










