大家好,我是网域小星球。
本篇是 C++ 面向对象的核心开篇,也是 C++ 面试重中之重 ------ 类与对象基础。面试官几乎都会问封装、构造函数、析构函数的用法,甚至让手撕代码。本篇全程聚焦面试考点,不冗余、只讲核心,代码 VS2022 直接运行,吃透就能应对类与对象的基础面试提问。
目录
[1. 核心定义(面试直接答)](#1. 核心定义(面试直接答))
[2. 类的基础语法(必写)](#2. 类的基础语法(必写))
[3. 访问权限(封装的核心,面试必问)](#3. 访问权限(封装的核心,面试必问))
[1. 核心作用](#1. 核心作用)
[2. 构造函数的 3 个特点(面试必背)](#2. 构造函数的 3 个特点(面试必背))
[3. 构造函数的 3 种写法(笔试常考)](#3. 构造函数的 3 种写法(笔试常考))
[4. 面试坑点(必避)](#4. 面试坑点(必避))
[1. 核心作用](#1. 核心作用)
[2. 析构函数的 3 个特点(面试必背)](#2. 析构函数的 3 个特点(面试必背))
[3. 析构函数用法(结合动态内存,面试常考)](#3. 析构函数用法(结合动态内存,面试常考))
[4. 面试考点(高频)](#4. 面试考点(高频))
[五、构造 / 析构函数的调用顺序(面试笔试题)](#五、构造 / 析构函数的调用顺序(面试笔试题))
一、核心学习目标(面试导向)
- 掌握 类与对象的概念(面向对象核心,面试必问)
- 理解 封装特性(C++ 三大特性之首,定义 + 用法)
- 熟练掌握 构造函数(写法、作用、面试常考重载)
- 熟练掌握 析构函数(写法、作用、内存释放逻辑)
- 避开构造 / 析构函数的常见面试坑点
二、类与对象的概念(面试基础题)
1. 核心定义(面试直接答)
- 类(class):抽象的模板,定义对象的属性(成员变量)和行为(成员函数),不占用内存;
- 对象:类的实例化,根据类模板创建的具体实体,占用内存;
- 关系:类是对象的 "蓝图",对象是类的 "具体实现"(比如 "人类" 是类,"张三" 是对象)。
2. 类的基础语法(必写)
cpp
#include <iostream>
#include <string>
using namespace std;
// 类的定义(class关键字)
class Person
{
// 访问权限(封装的核心)
public: // 公有:类内、类外都能访问(常用)
// 成员变量(属性)
string name;
int age;
// 成员函数(行为)
void showInfo()
{
cout << "姓名:" << name << ",年龄:" << age << endl;
}
private: // 私有:只有类内能访问(封装核心,隐藏细节)
string id; // 私有成员,类外无法直接访问
};
// 主函数:实例化对象
int main()
{
// 方式1:默认实例化
Person p1;
p1.name = "张三"; // 公有成员,类外可访问
p1.age = 20;
p1.showInfo(); // 调用成员函数
// 方式2:直接初始化
Person p2 = {"李四", 22};
p2.showInfo();
return 0;
}
3. 访问权限(封装的核心,面试必问)
C++ 用访问权限实现封装,三种权限(牢记):
public(公有):类内、类外均可访问(常用成员函数、对外暴露的属性);private(私有):只有类内可访问(核心属性,隐藏细节,比如身份证号、密码);protected(保护):类内可访问,子类可访问(后续继承章节讲解)。
面试考点:封装的作用?答:隐藏对象的核心细节,只对外暴露必要的接口,提高代码安全性、可维护性。
三、构造函数(面试必考,重中之重)
1. 核心作用
对象创建时自动调用,用于初始化对象的成员变量(避免成员变量为随机值),无需手动调用。
2. 构造函数的 3 个特点(面试必背)
- 函数名 和类名完全相同;
- 没有返回值(连 void 都不写);
- 可重载(面试常考,多构造函数适配不同初始化场景)。
3. 构造函数的 3 种写法(笔试常考)
cpp
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
string name;
int age;
// 1. 无参构造函数(默认构造)
Person()
{
name = "未知";
age = 0;
cout << "无参构造函数调用" << endl;
}
// 2. 有参构造函数(常用)
Person(string n, int a)
{
name = n;
age = a;
cout << "有参构造函数调用" << endl;
}
// 3. 拷贝构造函数(面试高频,用一个对象初始化另一个对象)
Person(const Person& p)
{
name = p.name; // 把p的name赋值给当前对象
age = p.age; // 把p的age赋值给当前对象
cout << "拷贝构造函数调用" << endl;
}
void showInfo()
{
cout << "姓名:" << name << ",年龄:" << age << endl;
}
};
int main()
{
Person p1; // 调用无参构造
Person p2("张三", 20); // 调用有参构造
Person p3 = p2; // 调用拷贝构造(用p2初始化p3)
p1.showInfo();
p2.showInfo();
p3.showInfo();
return 0;
}
4. 面试坑点(必避)
- 若手动写了有参构造,编译器 不会再自动生成无参构造(需手动写,否则报错);
- 拷贝构造函数的参数,必须加
const(避免修改原对象),且必须是引用(避免无限递归); - 无参构造和默认构造的区别:无参构造是手动写的,默认构造是编译器自动生成的(若未写任何构造)。
四、析构函数(面试必考,与构造函数成对出现)
1. 核心作用
对象销毁时自动调用,用于释放对象占用的资源(比如动态内存、文件句柄),无需手动调用。
2. 析构函数的 3 个特点(面试必背)
- 函数名:
~类名(波浪线 + 类名); - 没有返回值,也没有参数(不能重载,只能有一个);
- 若未手动写,编译器会自动生成默认析构函数(但无法释放动态内存,面试常考)。
3. 析构函数用法(结合动态内存,面试常考)
cpp
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
string name;
int* age; // 动态内存指针(面试常考场景)
// 有参构造:申请动态内存
Person(string n, int a)
{
name = n;
age = new int(a); // 申请堆内存,存储年龄
cout << "有参构造调用,申请内存" << endl;
}
// 析构函数:释放动态内存(必须手动写)
~Person()
{
if (age != nullptr) // 避免野指针
{
delete age; // 释放堆内存
age = nullptr; // 置空,防止野指针
}
cout << "析构函数调用,释放内存" << endl;
}
void showInfo()
{
cout << "姓名:" << name << ",年龄:" << *age << endl;
}
};
int main()
{
Person p("张三", 20);
p.showInfo();
// 函数结束,对象p销毁,自动调用析构函数,释放内存
return 0;
}
4. 面试考点(高频)
- 析构函数为什么不能有参数?答:析构函数是对象销毁时自动调用的,无法手动传递参数,所以不能重载,只能有一个。
- 什么时候必须手动写析构函数?答:当类的成员变量有动态内存(new 申请的内存)时,必须手动写析构函数释放,否则会造成内存泄漏。
五、构造 / 析构函数的调用顺序(面试笔试题)
牢记:先构造,后析构;构造顺序与对象创建顺序一致,析构顺序相反。
示例代码(笔试常考):
cpp
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "A构造" << endl; }
~A() { cout << "A析构" << endl; }
};
class B
{
public:
B() { cout << "B构造" << endl; }
~B() { cout << "B析构" << endl; }
};
int main()
{
A a; // 先创建A,调用A构造
B b; // 再创建B,调用B构造
// 析构顺序:先析构后创建的B,再析构先创建的A
return 0;
}
输出结果(面试直接答):A 构造 → B 构造 → B 析构 → A 析构
六、本章核心总结(面试速记)
- 类是模板(无内存),对象是实例(有内存),封装通过访问权限实现;
- 构造函数:类名相同、无返回值、可重载,对象创建时自动调用,用于初始化;
- 析构函数:~ 类名、无返回值、无参数,对象销毁时自动调用,用于释放资源;
- 动态内存必须在析构函数中释放,否则内存泄漏(面试重点);
- 构造顺序与对象创建一致,析构顺序相反(笔试常考)。
下期预告
C++ 从 0 入门(四)|类与对象进阶(继承、多态)+ 面试高频题(收官篇)