访问控制符

  • public:公有成员,类外部可以访问。
  • protected:保护成员,只有类的成员函数、友元函数以及派生类可以访问。
  • private:私有成员,只有类的成员函数和友元函数可以访问,派生类不能直接访问。

当类进行继承时,基类中的访问控制符会影响派生类对基类成员的访问权限。C++支持三种继承方式:

  • public继承:基类的public成员在派生类中保持public,protected成员保持protected,private成员依然无法访问。
  • protected继承:基类的public和protected成员在派生类中都变为protected,private成员依然无法访问。
  • private继承:基类的public和protected成员在派生类中都变为private,private成员依然无法访问。

友元

友元函数

#include <iostream>
using namespace std;

class Person {
private:
    string name;
    int age;
public:
    Person(string n, int a) : name(n), age(a) {}

    // 声明 friend 函数
    friend void showPersonInfo(const Person& p);
};

// 定义 friend 函数
void showPersonInfo(const Person& p) {
    cout << "Name: " << p.name << ", Age: " << p.age << endl;  // 可以访问 private 成员
}

int main() {
    Person p("Alice", 30);
    showPersonInfo(p);
    return 0;
}

友元类

#include <iostream>
using namespace std;

class Person {
private:
    string name;
    int age;

protected:
    int protectedVar;

public:
    Person(string n, int a) : name(n), age(a), protectedVar(100) {}

    // 将 FriendClass 声明为友元类
    friend class FriendClass;
};

// FriendClass 可以访问 Person 的 private 和 protected 成员
class FriendClass {
public:
    void displayPersonInfo(const Person& p) {
        // 可以访问 private 成员
        cout << "Name: " << p.name << endl;
        cout << "Age: " << p.age << endl;
        // 可以访问 protected 成员
        cout << "Protected Var: " << p.protectedVar << endl;
    }
};

int main() {
    Person person("Alice", 25);
    FriendClass friendClass;
    
    // 友元类访问 Person 的私有和保护成员
    friendClass.displayPersonInfo(person);

    return 0;
}

迭代器接口

支持 for 循环遍历的容器,主要依赖于迭代器接口的实现。为了支持 for 循环(尤其是 C++11 引入的范围 for 循环),容器必须实现以下两个方法:

  • begin():返回指向容器第一个元素的迭代器。
  • end():返回指向容器最后一个元素后面的迭代器。

如果你要让自己的类支持 for 循环遍历,你需要在该类中实现 begin() 和 end() 方法,返回一个迭代器,迭代器需要实现以下几个操作:

  • 解引用 (*):访问元素。
  • 递增 (++):移动到下一个元素。
  • 比较 (!=):检查迭代器是否到达末尾。
#include <iostream>

class MyContainer {
public:
    MyContainer(int* array, size_t size) : data(array), size(size) {}

    // 迭代器类
    class Iterator {
    public:
        Iterator(int* ptr) : current(ptr) {}

        int& operator*() { return *current; } // 解引用
        Iterator& operator++() {              // 前置递增
            current++;
            return *this;
        }
        bool operator!=(const Iterator& other) const { // 比较
            return current != other.current;
        }

    private:
        int* current;
    };

    Iterator begin() { return Iterator(data); }          // 返回起始迭代器
    Iterator end() { return Iterator(data + size); }     // 返回末尾迭代器

private:
    int* data;
    size_t size;
};

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    MyContainer container(arr, 5);

    for (int elem : container) {
        std::cout << elem << " ";  // 输出: 1 2 3 4 5
    }

    return 0;
}

STL 中的大部分容器都已经实现了begin、end接口,可以使用for循环,std::stack、std::queue 和 std::priority_queue 虽然内部使用容器,但它们本身不直接支持迭代器,因此不能直接在 for 循环中使用。