C++ 类 & 对象

在 C++ 中,**类(class)**是用于封装数据与操作(成员变量和成员函数)的用户自定义类型;**对象(object)**则是该类型的具体实例。下面按要点分章说明其定义、使用及高级特性。


1. 定义与访问控制

class Person {
public:             // 公有访问:外部可见
    Person(const std::string& n, int a);
    void   sayHello() const;

private:            // 私有访问:仅类内部可见
    std::string name;
    int         age;

protected:          // 受保护访问:在派生类中可见
    void log() const;
};
  • publicprivateprotected 决定成员可访问性。
  • struct 与 class 区别仅在默认访问权限:struct 默认 publicclass 默认 private

2. 构造函数 & 析构函数

Person::Person(const std::string& n, int a)
  : name(n), age(a)      // 成员初始化列表
{}

Person::~Person() {      // 析构函数,资源释放
    // 如需手动释放资源(一般用智能指针或容器管理)
}
  • 构造函数(Constructor)用于初始化对象,可重载多个参数版本。
  • 析构函数(Destructor, ~ClassName)在对象生命周期结束时调用,用于释放资源。
  • C++11 支持 default 与 deletePerson() = default; // 使用编译器生成的构造 Person(const Person&) = delete; // 禁用拷贝构造

3. 成员函数与常成员

void Person::sayHello() const {  // const 成员函数,不修改成员
    std::cout << "Hello, I'm " << name 
              << ", " << age << " years old.\n";
}
  • 常成员函数…() const)保证不修改对象状态,可被常对象调用。
  • 内联成员函数(在类内定义)自动含 inline 属性。

4. 数据封装与访问器

class Rectangle {
    double width, height;
public:
    double area() const { return width * height; }
    void   setSize(double w, double h) {
        width = w; height = h;
    }
};
  • 将成员设为私有,通过公有的 getter/setter(访问器/修改器)控制读写并可加入校验逻辑。

5. 静态成员与常量成员

class Counter {
public:
    static int count;            // 静态成员(类级别,共享)
    static int getCount() { return count; }
};
int Counter::count = 0;          // 必须在类外定义

class Config {
public:
    static constexpr double PI = 3.1415926535; // 编译期常量
};
  • static 成员属于类本身,不依赖对象。
  • constexpr 可用于常量初始化,编译期可求值。

6. 拷贝与移动语义

class Buffer {
    char* data;
    size_t size;
public:
    Buffer(size_t n): size(n) {
        data = new char[n];
    }
    ~Buffer() { delete[] data; }

    // 拷贝构造(深拷贝)
    Buffer(const Buffer& other)
      : size(other.size) {
        data = new char[size];
        std::memcpy(data, other.data, size);
    }
    // 移动构造(窃取资源)
    Buffer(Buffer&& other) noexcept
      : data(other.data), size(other.size) {
        other.data = nullptr;
        other.size = 0;
    }
    // 同理可定义拷贝/移动赋值运算符
};
  • Rule of Five:若定义自定义析构、拷贝/移动构造或赋值,最好都显式定义,以管理资源。

7. 继承与多态

class Shape {
public:
    virtual double area() const = 0; // 纯虚函数——抽象基类
    virtual ~Shape() = default;
};

class Circle : public Shape {
    double r;
public:
    Circle(double radius): r(radius) {}
    double area() const override {
        return 3.14159 * r * r;
    }
};
  • 基类定义 虚函数virtual),派生类用 override 标注重写。
  • 抽象类(含纯虚函数 =0)不可实例化。
  • 多态:通过基类指针/引用调用 area() 时,会动态绑定到派生类实现。

8. 对象的创建与存储

// 栈上
Person p{"Alice", 30};

// 堆上
auto* pp = new Person{"Bob", 25};
delete pp;

// 智能指针管理
auto sp = std::make_shared<Person>("Carol", 28);
  • 对象可在栈、堆或静态区创建,推荐使用智能指针(unique_ptrshared_ptr)管理动态对象。

9. 友元(Friend)

class A {
    int secret;
    friend void reveal(const A&); // declare friend
};

void reveal(const A& a) {
    std::cout << a.secret;       // 访问私有成员
}
  • 友元函数/类可访问类的私有和受保护成员,用于重载输出运算符等场景。

10. 模板与泛型

template<typename T>
class Box {
    T value;
public:
    Box(const T& v): value(v) {}
    T get() const { return value; }
};
  • 类模板支持泛型编程,可像 Box<int>Box<std::string> 一样实例化多种类型。

小结

  • 是封装数据和操作的蓝图,对象是其实例。
  • 掌握构造/析构、拷贝/移动语义可有效管理资源。
  • 使用访问控制、虚函数、多态与模板,可设计灵活、安全且高效的 C++ 程序。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注