026-C++ 类 & 对象

类和对象是 C++ 中面向对象编程(OOP)的核心。类提供了数据和操作的封装,而对象是类的实例。通过类和对象可以实现数据抽象、封装、继承和多态等特性。


1. 类的基本定义

1.1 类的定义

语法
class 类名 {
private: // 私有成员(默认访问权限)
    数据类型 成员变量;
    返回类型 成员函数();

public: // 公有成员
    数据类型 成员变量;
    返回类型 成员函数();
};

1.2 对象的创建

对象是类的实例,通过类定义可以创建一个或多个对象。


示例:基本类定义和对象创建

#include 
using namespace std;

class Person {
public:
    string name; // 公有成员变量
    int age;

    void introduce() { // 公有成员函数
        cout << "Hi, I am " << name << ", and I am " << age << " years old." << endl;
    }
};

int main() {
    Person p1; // 创建对象 p1
    p1.name = "Alice";
    p1.age = 25;

    p1.introduce(); // 调用成员函数

    return 0;
}

输出

Hi, I am Alice, and I am 25 years old.

2. 类的访问权限

访问权限决定了类的成员变量和成员函数是否可以被外部访问。

2.1 访问权限类型

  • public:公有成员,类外部可以直接访问。
  • private:私有成员,只有类内部可以访问(默认权限)。
  • protected:受保护成员,只有类内部和派生类可以访问。
示例
#include 
using namespace std;

class Person {
private:
    int id; // 私有成员变量

protected:
    string secret; // 受保护成员变量

public:
    string name; // 公有成员变量

    void setId(int idVal) { // 公有成员函数
        id = idVal;
    }

    void display() {
        cout << "ID: " << id << ", Name: " << name << endl;
    }
};

int main() {
    Person p;
    p.name = "Bob";
    p.setId(101); // 通过公有函数访问私有成员
    p.display();

    return 0;
}

输出

ID: 101, Name: Bob

3. 构造函数和析构函数

3.1 构造函数

构造函数用于初始化对象,在对象创建时自动调用。

特点
  • 函数名与类名相同。
  • 没有返回值。
  • 支持重载(多个构造函数)。
示例
#include 
using namespace std;

class Person {
public:
    string name;
    int age;

    // 构造函数
    Person(string n, int a) {
        name = n;
        age = a;
    }

    void introduce() {
        cout << "Hi, I am " << name << ", and I am " << age << " years old." << endl;
    }
};

int main() {
    Person p1("Alice", 25); // 调用带参数的构造函数
    p1.introduce();

    return 0;
}

输出

Hi, I am Alice, and I am 25 years old.

3.2 默认构造函数和析构函数

  • 默认构造函数:如果没有定义构造函数,编译器会提供一个默认的无参构造函数。
  • 析构函数:用于在对象销毁时释放资源。析构函数名称前有 ~
示例:析构函数
#include 
using namespace std;

class Person {
public:
    Person() {
        cout << "Constructor called." << endl;
    }

    ~Person() {
        cout << "Destructor called." << endl;
    }
};

int main() {
    Person p1; // 创建对象时调用构造函数
    return 0;  // 程序结束时调用析构函数
}

输出

Constructor called.
Destructor called.

4. 成员函数

4.1 定义与实现

成员函数可以在类内定义,也可以在类外实现。

示例:类内定义
class Person {
public:
    void introduce() {
        cout << "Hello!" << endl;
    }
};
示例:类外实现
class Person {
public:
    void introduce(); // 函数声明
};

// 函数实现
void Person::introduce() {
    cout << "Hello!" << endl;
}

4.2 常量成员函数

常量成员函数不能修改类的成员变量,且只能调用其他常量成员函数。

示例
#include 
using namespace std;

class Person {
private:
    string name;

public:
    Person(string n) : name(n) {}

    void display() const { // 常量成员函数
        cout << "Name: " << name << endl;
    }
};

int main() {
    Person p("Alice");
    p.display();

    return 0;
}

5. 静态成员

5.1 静态成员变量

静态成员变量属于类,而不是某个对象。所有对象共享同一个静态成员变量。

示例
#include 
using namespace std;

class Person {
public:
    static int population; // 静态成员变量声明

    Person() {
        population++;
    }
};

// 静态成员变量定义和初始化
int Person::population = 0;

int main() {
    Person p1, p2;

    cout << "Population: " << Person::population << endl; // 访问静态成员变量

    return 0;
}

输出

Population: 2

5.2 静态成员函数

静态成员函数只能访问静态成员变量,不能访问非静态成员。

示例
#include 
using namespace std;

class Person {
public:
    static int population;

    static void displayPopulation() { // 静态成员函数
        cout << "Population: " << population << endl;
    }
};

int Person::population = 0;

int main() {
    Person::population = 5;
    Person::displayPopulation(); // 调用静态成员函数

    return 0;
}

输出

Population: 5

6. 对象的动态分配

对象可以在堆上动态分配内存,使用 newdelete 管理。

示例
#include 
using namespace std;

class Person {
public:
    string name;

    Person(string n) : name(n) {}
    void introduce() {
        cout << "Hi, I am " << name << "." << endl;
    }
};

int main() {
    Person* p = new Person("Alice"); // 动态分配对象
    p->introduce();

    delete p; // 释放对象内存

    return 0;
}

输出

Hi, I am Alice.

7. 类的高级特性

7.1 友元函数和友元类

友元函数或友元类可以访问类的私有和受保护成员。

友元函数
#include 
using namespace std;

class Person {
private:
    string name;

public:
    Person(string n) : name(n) {}

    friend void display(const Person& p); // 声明友元函数
};

void display(const Person& p) { // 定义友元函数
    cout << "Name: " << p.name << endl;
}

int main() {
    Person p("Alice");
    display(p);

    return 0;
}

输出

Name: Alice

7.2 对象数组

可以创建包含多个对象的数组。

示例
#include 
using namespace std;

class Person {
public:
    string name;

    Person(string n) : name(n) {}
    void introduce() {
        cout << "Hi, I am " << name << "." << endl;
    }
};

int main() {
    Person people[] = {Person("Alice"), Person("Bob"), Person("Charlie")};

    for (int i = 0; i < 3; i++) {
        people[i].introduce();
    }

    return 0;
}

输出

Hi, I am Alice.
Hi, I am Bob.
Hi, I am Charlie.

8. 总结

8.1 核心概念

  • 类与对象:类是蓝图,对象是实例。
  • 访问权限publicprivateprotected
  • 构造函数与析构函数:用于对象的初始化和销毁。
  • 静态成员:类共享的数据和方法。

8.2 高级功能

  • 友元:允许外部函数或类访问私有成员。
  • 动态分配:通过 newdelete 管理对象内存。
  • 对象数组:存储多个对象。

C++ 的类和对象为面向对象编程提供了强大的支持,通过封装、继承、多态等特性,可以构建灵活、健壮的程序。


C++ 类与对象:深入与高级应用

在之前的部分,我们学习了类与对象的基础知识,包括类的定义、访问权限、构造函数、析构函数、静态成员、友元等内容。接下来将深入探讨类和对象的高级特性,包括拷贝构造函数、运算符重载、继承、多态、虚函数等。


9. 拷贝构造函数

9.1 什么是拷贝构造函数?

拷贝构造函数用于通过一个已存在的对象来初始化另一个对象。默认情况下,C++ 会提供一个浅拷贝的拷贝构造函数,但在对象包含动态分配的资源时,通常需要自定义拷贝构造函数。

9.2 默认拷贝构造函数(浅拷贝)

浅拷贝仅复制对象的成员变量,不会复制动态分配的内存。

示例

#include 
using namespace std;

class Person {
public:
    string name;

    Person(string n) : name(n) {}

    void display() {
        cout << "Name: " << name << endl;
    }
};

int main() {
    Person p1("Alice");
    Person p2 = p1; // 调用默认拷贝构造函数

    p2.display();

    return 0;
}

输出

Name: Alice

9.3 自定义拷贝构造函数(深拷贝)

当类中包含指针成员时,默认的浅拷贝会导致多个对象共享同一块内存,可能引发问题(如多次释放同一内存)。此时,需要自定义拷贝构造函数,实现深拷贝。

示例

#include 
#include 
using namespace std;

class Person {
private:
    char* name;

public:
    // 构造函数
    Person(const char* n) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
    }

    // 自定义拷贝构造函数
    Person(const Person& other) {
        name = new char[strlen(other.name) + 1];
        strcpy(name, other.name);
    }

    // 析构函数
    ~Person() {
        delete[] name;
    }

    void display() {
        cout << "Name: " << name << endl;
    }
};

int main() {
    Person p1("Alice");
    Person p2 = p1; // 调用自定义拷贝构造函数

    p2.display();

    return 0;
}

输出

Name: Alice

10. 运算符重载

C++ 支持运算符重载,允许为类对象自定义运算行为。

10.1 重载基本运算符

示例:重载 + 运算符
#include 
using namespace std;

class Complex {
private:
    double real, imag;

public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载 + 运算符
    Complex operator+(const Complex& other) {
        return Complex(real + other.real, imag + other.imag);
    }

    void display() {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main() {
    Complex c1(1.2, 3.4);
    Complex c2(5.6, 7.8);

    Complex c3 = c1 + c2; // 使用重载的 + 运算符
    c3.display();

    return 0;
}

输出

6.8 + 11.2i

10.2 重载流插入和提取运算符

流插入(<<)和提取(>>)运算符用于输入和输出类对象。

示例

#include 
using namespace std;

class Person {
private:
    string name;
    int age;

public:
    Person(string n = "Unknown", int a = 0) : name(n), age(a) {}

    // 重载 << 运算符
    friend ostream& operator<<(ostream& os, const Person& p) {
        os << "Name: " << p.name << ", Age: " << p.age;
        return os;
    }

    // 重载 >> 运算符
    friend istream& operator>>(istream& is, Person& p) {
        is >> p.name >> p.age;
        return is;
    }
};

int main() {
    Person p1;

    cout << "Enter name and age: ";
    cin >> p1;

    cout << "Person details: " << p1 << endl;

    return 0;
}

输入

Alice 25

输出

Person details: Name: Alice, Age: 25

11. 继承

继承允许一个类(子类)从另一个类(父类)继承成员变量和成员函数。

11.1 基本继承

示例
#include 
using namespace std;

class Person {
public:
    string name;

    void introduce() {
        cout << "Hi, I am " << name << "." << endl;
    }
};

class Student : public Person { // Student 继承自 Person
public:
    int grade;

    void study() {
        cout << name << " is studying in grade " << grade << "." << endl;
    }
};

int main() {
    Student s;
    s.name = "Alice";
    s.grade = 10;

    s.introduce(); // 调用基类成员函数
    s.study();     // 调用派生类成员函数

    return 0;
}

输出

Hi, I am Alice.
Alice is studying in grade 10.

11.2 访问权限与继承

基类成员访问权限 public 继承 protected 继承 private 继承
public public protected private
protected protected protected private
private 不可访问 不可访问 不可访问

12. 多态

多态允许基类指针或引用调用派生类的函数,分为 静态多态(函数重载、运算符重载)和 动态多态(虚函数)。

12.1 虚函数

示例:动态多态
#include 
using namespace std;

class Person {
public:
    virtual void introduce() { // 虚函数
        cout << "I am a person." << endl;
    }
};

class Student : public Person {
public:
    void introduce() override { // 重写虚函数
        cout << "I am a student." << endl;
    }
};

int main() {
    Person* p = new Student(); // 基类指针指向派生类对象
    p->introduce();            // 调用派生类的函数

    delete p;
    return 0;
}

输出

I am a student.

12.2 纯虚函数和抽象类

纯虚函数是没有实现的虚函数,包含纯虚函数的类称为抽象类。

示例
#include 
using namespace std;

class Shape {
public:
    virtual void draw() = 0; // 纯虚函数
};

class Circle : public Shape {
public:
    void draw() override {
        cout << "Drawing a circle." << endl;
    }
};

int main() {
    Shape* s = new Circle();
    s->draw();

    delete s;
    return 0;
}

输出

Drawing a circle.

13. 类模板

类模板允许创建通用的类以适应不同的数据类型。

示例
#include 
using namespace std;

template 
class Box {
private:
    T value;

public:
    Box(T v) : value(v) {}

    void display() {
        cout << "Value: " << value << endl;
    }
};

int main() {
    Box intBox(10);
    Box strBox("Hello");

    intBox.display();
    strBox.display();

    return 0;
}

输出

Value: 10
Value: Hello

14. 总结

14.1 核心特性

  1. 封装:通过类隐藏实现细节。
  2. 继承:实现代码复用和层次结构。
  3. 多态:通过虚函数实现动态绑定。
  4. 运算符重载:自定义对象的运算行为。

14.2 高级特性

  • 拷贝构造函数:控制对象复制过程。
  • 虚函数与抽象类:实现动态多态。
  • 类模板:支持泛型编程。

通过掌握类与对象的特性与高级应用,可以设计健壮、可扩展、灵活的 C++ 程序。

你可能感兴趣的:(C++,c++,开发语言)