当前位置:首页 > 技术 > 正文内容

C++类与对象的核心机制

访客 技术 2026年6月19日 1

默认成员函数概览 在C++中,当用户未显式定义时,编译器会自动为类生成六个默认成员函数。其中,有四个是开发者必须掌握的关键函数:构造函数、析构函数、拷贝构造函数和赋值操作符。这些函数直接影响对象的生命周期管理与资源控制。

构造函数的作用与实现 构造函数是一种特殊的成员函数,其主要职责是在对象创建时完成初始化工作,而非负责内存分配(局部变量的内存由栈帧自动分配)。它替代了传统代码中手动调用的初始化函数,实现自动化初始化。

构造函数具有以下特性:

  • 函数名与类名一致
  • 无返回类型
  • 对象创建时自动调用
  • 支持重载
  • 未定义时由编译器自动生成
  • 无参构造函数也称为"零参数构造"

建议对自定义类型使用初始化列表进行成员初始化,以提高效率并避免潜在错误。

#include <iostream>
using namespace std;

class Date {
public:
    // 全缺省构造函数
    Date(int year = 1, int month = 2, int day = 3) 
        : _year(year), _month(month), _day(day) {}

    void Print() const {
        cout << _year << " " << _month << " " << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};

int main() {
    Date d1;           // 使用全缺省构造
    d1.Print();

    Date d2(2022, 3, 4); // 显式传参
    d2.Print();

    Date d3(2023);     // 部分参数省略
    d3.Print();

    return 0;
}

对于包含自定义类型成员的类,若该成员没有默认构造函数,则必须通过初始化列表显式指定其构造方式,否则将导致编译错误。

class Stack {
public:
    Stack(size_t capacity = 4)
        : _data(new int[capacity])
        , _size(0)
        , _cap(capacity) {}

private:
    int* _data;
    size_t _size;
    size_t _cap;
};

class MyQueue {
public:
private:
    Stack s1;
    Stack s2;
};

int main() {
    MyQueue q; // s1、s2 会分别调用各自的构造函数
    return 0;
}

析构函数的设计原则 析构函数用于在对象销毁前清理资源,如释放动态内存、关闭文件句柄等。尽管局部对象的内存由栈自动回收,但若对象持有外部资源,则需通过析构函数主动释放。

析构函数特点:

  • 名称以 ~ 开头,后接类名
  • 无参数,无返回值
  • 对象生命周期结束时自动调用
  • 若无资源需清理,可不显式定义
  • 析构顺序遵循"后定义先析构"的规则
class Date {
public:
    Date(int y = 1, int m = 2, int d = 3)
        : _year(y), _month(m), _day(d) {}

    ~Date() {
        cout << "Date object destroyed!" << endl;
    }

    void Print() const {
        cout << _year << " " << _month << " " << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};

int main() {
    Date d1;
    d1.Print();

    Date d2(2022, 3, 4);
    d2.Print();

    return 0;
}

拷贝构造函数详解 拷贝构造函数是一个特殊构造函数,其形参为本类类型的常引用。当对象以值方式传递或定义时,会触发此函数调用。

关键点:

  • 必须使用引用传参,防止无限递归
  • 编译器会在未定义时生成默认版本,执行逐成员浅拷贝
  • 自定义类型成员将调用其自身的拷贝构造函数
class Date {
public:
    Date(int y = 1, int m = 2, int d = 3)
        : _year(y), _month(m), _day(d) {}

    // 拷贝构造函数
    Date(const Date& other)
        : _year(other._year)
        , _month(other._month)
        , _day(other._day) {}

    void Print() const {
        cout << _year << " " << _month << " " << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};

void func(Date d) {
    cout << "Address: " << &d << endl;
    d.Print();
}

int main() {
    Date d1;
    Date d2(d1);  // 调用拷贝构造
    d2.Print();

    func(d1);     // 值传递触发拷贝构造

    return 0;
}

运算符重载机制 运算符重载允许用户为自定义类型定义类似内置类型的操作行为,如加减比较等。

语法结构:

  • 函数名为 operator+operator==
  • 可作为成员函数或非成员函数
  • 成员函数隐含 this 指针,参数数量比操作数少一

前置与后置自增/自减需区分:

  • 前置:operator++()
  • 后置:operator++(int) —— 多一个 int 参数用于重载区分
class Date {
public:
    Date(int y = 1, int m = 2, int d = 3)
        : _year(y), _month(m), _day(d) {}

    bool operator==(const Date& other) const {
        return _year == other._year && 
               _month == other._month && 
               _day == other._day;
    }

    void Print() const {
        cout << _year << " " << _month << " " << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};

int main() {
    Date d1;
    Date d2(d1);

    bool result = d1 == d2;  // 等价于 d1.operator==(d2)
    cout << "Equal? " << result << endl;

    return 0;
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。