c++的学习与总结(2.类和对象上)
2026/7/5 15:31:30 网站建设 项目流程

一、类的基本属性

1. 类的定义

类是用class关键字定义的用户自定义类型,可以包含成员变量和成员函数。

2. 代码示例

class A { // 成员变量 int _a; // 成员函数 void func() {} };

3. 类的成员

3.1成员变量(类内部的变量)
  • 成员变量一般加_前缀,与函数参数做区分

3.2 成员函数(类内部的函数)
  • 在类体内定义的成员函数,编译器会隐式视为内联函数(但最终是否内联由编译器决定)

4.类的内存分配

成员类型是否占对象内存说明
成员变量创建对象时分配,对齐规则与结构体相同
成员函数不占代码存在代码段,对象中不存储
空类(无成员变量)占 1 字节用于占位,标识对象存在

5. 类域

  • 类域用于区分不同类之间的成员

  • 头文件里放类的声明,在对应的.cpp文件中定义成员函数时,需要用类名::指明函数属于哪个类 .例如:void Stack::init() { }

6. 与struct 的区别

  • struct在 C++ 中也可以定义类

  • 区别:class默认访问权限为privatestructpublic


二、对象创建

1. 概念

类名 + 变量名

2. 代码示例

A a;

三、访问限定符(public / private)

1. 概念

决定这个成员能不能被外界访问

2. 代码示例

class A { public: void func(); // 类外可调用 private: int _a; // 类外不可访问 };

3. 特性

  • public:类内外都能访问,通常放成员函数

  • private:只有类内部能访问,通常放成员变量

  • protected:目前和private一样(继承时才有区别)

  • 限定符作用域从它开始到下一个限定符结束

  • class默认privatestruct默认public

4. 补充

一般public写的是成员函数,private写的是成员变量


四、构造函数

1. 概念

函数名与类名相同,无返回值,用于初始化类的对象

2. 代码示例

class Date { public: Date(int y, int m, int d) { _year = y; _month = m; _day = d; } private: int _year; int _month; int _day; };

3. 特性

  • 可以重载,可以有缺省参数

  • 一旦用户写了任何构造,系统不再生成默认构造

  • 调用默认构造不加括号:Date d;

  • 三种默认构造
    类型形式何时生成/调用
    无参构造Date() {}用户显式写出
    全缺省构造Date(int y=1, int m=1, int d=1) {}用户显式写出
    编译器默认生成用户没写任何构造时对内置类型不初始化(值不确定),对自定义类型调用其默认构造

注意:

在使用默认构造时,用Data t=Data();这样的形式初始化时会调用变量的值初始化,比如int为0,自定义变量调相应的初始构造;用Data t;这样的形式会用随机值。

若使用自己的构造函数,有缺省值的话,Data t;这样的形式会用缺省值

五、析构函数

1. 概念

~类名,无返回值无参数,是对象的销毁

2. 代码示例

class A { public: ~A() { // 释放资源 } };

3. 特性

  • 没有动态内存时默认析构足够,当有动态内存时要手动释放

  • 析构顺序与构造相反,后创建的先销毁


六、初始化列表

1. 概念

冒号开头,逗号分隔,在构造函数体之前执行

2. 代码示例

class Date { public: Date(int y, int m, int d) : _year(y), _month(m), _day(d) {} private: int _year; int _month; int _day; };

3. 特性

  • 初始化顺序按声明顺序,建议列表顺序与之相同(易错点)

  • 效率比函数体内赋值高

  • 成员类型是否必须在初始化列表初始化原因
    const成员必须const变量只能初始化,不能赋值
    引用成员必须引用必须绑定到对象,且不能重新绑定
    没有默认构造的对象成员必须无法在函数体内构造(没有默认构造可用)
    普通内置类型可选可以在函数体内赋值,但列表效率更高

七、this 指针

1. 概念

指向当前对象的指针

2. 代码示例

class A { public: void set(int a) { this->_a = a; } private: int _a; };

3. 特性

  • 区分同名参数和成员变量:this->_a = a;

  • this是指针常量,不能修改指向

  • 静态成员函数没有this

  • 每个非静态成员函数都有一个隐含的this指针,指向调用对象


八、拷贝构造

1. 概念

构造函数的重载,参数是同类对象的const引用,用已有对象初始化新对象时调用

2. 代码示例

class Date { public: Date(const Date& d) { _year = d._year; _month = d._month; _day = d._day; } private: int _year; int _month; int _day; };

3. 特性

  • 必须用引用,否则无限递归

  • 如果不写,编译器生成默认拷贝构造(浅拷贝)

  • 写法是否调用拷贝构造说明
    Date d2(d1);调用直接初始化
    Date d2 = d1;调用拷贝初始化(编译器可能优化为直接构造)
    func(d1)(传值参数)调用实参拷贝给形参
    return d1(返回值)调用局部对象拷贝给返回值(可能被 RVO 优化掉)
    Date d2; d2 = d1;不调用这是赋值重载,不是拷贝构造

九、浅拷贝 vs 深拷贝

1. 概念

浅拷贝拷贝地址,深拷贝拷贝内容

2. 代码示例

// 浅拷贝(默认) // String s2(s1); // s1 和 s2 的 _data 指向同一块内存 // 深拷贝 String(const String& s) { _data = new char[strlen(s._data) + 1]; strcpy(_data, s._data); }

3特性

对比项浅拷贝深拷贝
实现方式编译器默认生成用户手动实现
拷贝内容逐字节拷贝成员变量的值拷贝指针指向的内容,并开辟新内存
指针成员只拷贝地址(指针的值)拷贝指针指向的数据,新对象拥有独立内存
多个对象的关系多个对象指向同一块内存每个对象有自己的内存,互不干扰
资源释放多次释放同一块内存 → double free各自释放自己的内存,安全
适用场景没有动态内存成员的简单类类中有指向动态内存的指针成员(如char*int*
是否可依赖默认不可依赖(有指针时)必须自己实现

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询