5. 类和对象

类的基本概念

1. 类的定义

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Person {
private:
    std::string name;
    int age;
    
public:
    // 构造函数
    Person() : name("Unknown"), age(0) {}  // 默认构造函数
    Person(const std::string& n, int a) : name(n), age(a) {}  // 带参构造函数
    
    // 成员函数
    void setName(const std::string& n) { name = n; }
    void setAge(int a) { age = a; }
    std::string getName() const { return name; }
    int getAge() const { return age; }
    
    // 析构函数
    ~Person() {}
};

2. 访问控制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class AccessExample {
private:
    int privateVar;     // 只能在类内部访问
    
protected:
    int protectedVar;   // 可在类内部和派生类中访问
    
public:
    int publicVar;      // 可在任何地方访问
    
    void accessDemo() {
        privateVar = 1;   // OK
        protectedVar = 2; // OK
        publicVar = 3;    // OK
    }
};

3. 静态成员

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Counter {
private:
    static int count;   // 静态成员变量声明
    int id;
    
public:
    Counter() : id(++count) {}
    
    static int getCount() {  // 静态成员函数
        return count;
    }
    
    int getId() const {
        return id;
    }
};

// 静态成员变量定义
int Counter::count = 0;

// 使用示例
Counter c1, c2;
std::cout << Counter::getCount() << "\n";  // 输出2

构造和析构

1. 构造函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyClass {
private:
    int* data;
    
public:
    // 默认构造函数
    MyClass() : data(new int(0)) {}
    
    // 带参构造函数
    MyClass(int value) : data(new int(value)) {}
    
    // 拷贝构造函数
    MyClass(const MyClass& other) : data(new int(*other.data)) {}
    
    // 移动构造函数
    MyClass(MyClass&& other) noexcept : data(other.data) {
        other.data = nullptr;
    }
    
    // 析构函数
    ~MyClass() {
        delete data;
    }
};

2. 初始化列表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Rectangle {
private:
    int width;
    int height;
    const double ratio;
    
public:
    // 使用初始化列表初始化成员
    Rectangle(int w, int h)
        : width(w)
        , height(h)
        , ratio(static_cast<double>(w) / h) {}
};

3. 委托构造函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Delegate {
private:
    int x, y, z;
    
public:
    // 主构造函数
    Delegate(int x, int y, int z) : x(x), y(y), z(z) {}
    
    // 委托构造函数
    Delegate() : Delegate(0, 0, 0) {}
    Delegate(int x) : Delegate(x, 0, 0) {}
    Delegate(int x, int y) : Delegate(x, y, 0) {}
};

继承和多态

1. 基类和派生类

 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 基类
class Shape {
protected:
    std::string name;
    
public:
    Shape(const std::string& n) : name(n) {}
    
    virtual double area() const = 0;  // 纯虚函数
    virtual double perimeter() const = 0;
    
    virtual ~Shape() {}  // 虚析构函数
};

// 派生类
class Circle : public Shape {
private:
    double radius;
    
public:
    Circle(double r) : Shape("Circle"), radius(r) {}
    
    double area() const override {
        return M_PI * radius * radius;
    }
    
    double perimeter() const override {
        return 2 * M_PI * radius;
    }
};

class Rectangle : public Shape {
private:
    double width, height;
    
public:
    Rectangle(double w, double h)
        : Shape("Rectangle"), width(w), height(h) {}
    
    double area() const override {
        return width * height;
    }
    
    double perimeter() const override {
        return 2 * (width + height);
    }
};

2. 多态性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
void printArea(const Shape& shape) {
    std::cout << "Area: " << shape.area() << "\n";
}

// 使用示例
Circle circle(5);
Rectangle rect(4, 6);

printArea(circle);  // 多态调用Circle::area()
printArea(rect);    // 多态调用Rectangle::area()

// 使用基类指针
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>(5));
shapes.push_back(std::make_unique<Rectangle>(4, 6));

for (const auto& shape : shapes) {
    printArea(*shape);  // 多态调用
}

3. 虚函数和抽象类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class AbstractBase {
public:
    virtual void method1() = 0;  // 纯虚函数
    virtual void method2() = 0;
    
    virtual ~AbstractBase() = default;
};

class Concrete : public AbstractBase {
public:
    void method1() override {
        std::cout << "Implemented method1\n";
    }
    
    void method2() override {
        std::cout << "Implemented method2\n";
    }
};

运算符重载

1. 成员函数重载

 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
27
28
29
30
31
32
33
34
35
class Complex {
private:
    double real, imag;
    
public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}
    
    // 重载加法运算符
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }
    
    // 重载赋值运算符
    Complex& operator=(const Complex& other) {
        if (this != &other) {
            real = other.real;
            imag = other.imag;
        }
        return *this;
    }
    
    // 重载复合赋值运算符
    Complex& operator+=(const Complex& other) {
        real += other.real;
        imag += other.imag;
        return *this;
    }
    
    // 重载下标运算符
    double& operator[](int index) {
        if (index == 0) return real;
        if (index == 1) return imag;
        throw std::out_of_range("Index out of range");
    }
};

2. 友元函数重载

 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
27
28
29
30
31
32
class String {
private:
    char* str;
    
public:
    String(const char* s = "") {
        str = new char[strlen(s) + 1];
        strcpy(str, s);
    }
    
    ~String() { delete[] str; }
    
    // 声明友元函数
    friend std::ostream& operator<<(std::ostream& os, const String& s);
    friend std::istream& operator>>(std::istream& is, String& s);
};

// 重载输出运算符
std::ostream& operator<<(std::ostream& os, const String& s) {
    os << s.str;
    return os;
}

// 重载输入运算符
std::istream& operator>>(std::istream& is, String& s) {
    char temp[1000];
    is >> temp;
    delete[] s.str;
    s.str = new char[strlen(temp) + 1];
    strcpy(s.str, temp);
    return is;
}

3. 类型转换运算符

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Fraction {
private:
    int num, den;
    
public:
    Fraction(int n = 0, int d = 1) : num(n), den(d) {}
    
    // 转换为double的运算符
    operator double() const {
        return static_cast<double>(num) / den;
    }
    
    // 转换为bool的运算符
    explicit operator bool() const {
        return num != 0;
    }
};

// 使用示例
Fraction f(3, 2);
double d = f;      // 调用operator double()
if (f) {           // 调用operator bool()
    std::cout << "Fraction is non-zero\n";
}

特殊成员函数

1. Rule of Five

 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Resource {
private:
    int* data;
    
public:
    // 构造函数
    Resource(int value = 0) : data(new int(value)) {}
    
    // 析构函数
    ~Resource() {
        delete data;
    }
    
    // 拷贝构造函数
    Resource(const Resource& other) : data(new int(*other.data)) {}
    
    // 拷贝赋值运算符
    Resource& operator=(const Resource& other) {
        if (this != &other) {
            int* newData = new int(*other.data);
            delete data;
            data = newData;
        }
        return *this;
    }
    
    // 移动构造函数
    Resource(Resource&& other) noexcept : data(other.data) {
        other.data = nullptr;
    }
    
    // 移动赋值运算符
    Resource& operator=(Resource&& other) noexcept {
        if (this != &other) {
            delete data;
            data = other.data;
            other.data = nullptr;
        }
        return *this;
    }
};

2. 禁用特殊成员函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Uncopyable {
public:
    Uncopyable() = default;
    
    // 禁用拷贝
    Uncopyable(const Uncopyable&) = delete;
    Uncopyable& operator=(const Uncopyable&) = delete;
    
    // 允许移动
    Uncopyable(Uncopyable&&) = default;
    Uncopyable& operator=(Uncopyable&&) = default;
};

57.12k 字
43篇文章