C/C++面经
- C/C++
-
- 一、讲讲C++中的封装,继承,多态
- 二、再讲讲模板编程
- 三、请解释STL中的空间配置器(allocator)的作用
- 四、请解释STL中的map和unordered_map的区别
- 五、讲讲内存对齐
- 六、讲讲计算机的大小端存储
- 七、什么是智能指针,讲讲智能指针?(重点)
- 八、new/delete和malloc/free的区别 ?
- 九、讲讲右值引用的移动语义
- 十、讲讲const和static
- 十一、函数重载底层有了解过吗?
- 十二、如何去检查你代码中可能存在的内存泄露问题
- 十三、设计一个单例模式
- 十四、vector频繁的进行push_back会有什么影响?怎么解决?
- 十五、函数指针和指针函数区别?
- 其他
C/C++
一、讲讲C++中的封装,继承,多态
1. 封装
封装就是将数据(成员变量)和操作数据的方法(成员函数)绑定在一起,并对外隐藏实现细节,只暴露必要的接口。通过封装,可以控制数据的访问权限,防止外部直接修改内部数据,从而提高代码的安全性和可维护性。
- 使用
private、protected和public访问修饰符来控制成员的访问权限。private:只能在类内部访问。protected:可以在类内部和派生类中访问。public:可以在任何地方访问。
2. 继承
继承是面向对象编程(OOP)的核心概念之一,它允许一个类(派生类)基于另一个类(基类)来构建,从而实现代码的重用和扩展。继承使得派生类可以继承基类的属性和方法,并可以在派生类中添加新的属性和方法,或重写基类的方法。
访问修饰符(public、protected、private)决定了基类成员在派生类中的访问权限。
- 派生类的构造函数会首先调用基类的构造函数,然后再执行派生类自己的构造函数。
- 如果基类没有默认构造函数,派生类必须显式调用基类的构造函数。
- 派生类的析构函数会首先执行派生类自己的析构函数,然后再调用基类的析构函数。
3. 多态
多态简单来说就是不同类对象调用同一个函数方法有不同的响应
eg :动物(函数方法)都会叫,但狗叫和猫叫不一样(类对象)
多态是在继承的基础上实现的
多态允许不同的类对同一消息(方法调用)作出不同的响应。多态性使得程序可以在运行时根据对象的实际类型来调用相应的方法,从而实现更灵活和可扩展的代码设计。
多态分为两种类型:
- 编译时多态(静态多态):通过函数重载和运算符重载实现。
- 运行时多态(动态多态):通过虚函数和继承实现。
虚函数(重点)
虚函数是在基类中使用 virtual 关键字声明的函数,派生类可以重写(override)这些函数。通过基类指针或引用调用虚函数时,实际调用的是派生类中重写的函数。
示例:
#include <iostream>
using namespace std;
class Animal {
public:
virtual void speak() {
// 虚函数
cout << "Animal speaks" << endl;
}
};
class Dog : public Animal {
public:
void speak() override {
// 重写虚函数
cout << "Dog barks" << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
// 重写虚函数
cout << "Cat meows" << endl;
}
};
int main() {
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->speak(); // 输出: Dog barks
animal2->speak(); // 输出: Cat meows
delete animal1;
delete animal2;
return 0;
}
关键点:
- 使用 virtual 关键字声明虚函数。
- 派生类中使用 override 关键字(可选,但推荐)明确表示重写虚函数。
- 通过基类指针或引用调用虚函数时,实际调用的是派生类的函数。
纯虚函数和抽象类
纯虚函数是在基类中声明但没有实现的虚函数,派生类必须重写纯虚函数。包含纯虚函数的类称为抽象类,不能实例化。
示例:
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() = 0; // 纯虚函数
};
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing a Circle" << endl;
}
};
class Square : public Shape {
public:
void draw() override {
cout << "Drawing a Square" << endl;
}
};
int main() {
Shape* shape1 = new Circle();
Shape* shape2 = new Square();
shape1->draw(); // 输出: Drawing a Circle
shape2->draw(); // 输出: Drawing a Square
delete shape1;
delete shape2;
return 0;
}
虚析构函数
如果基类的析构函数不是虚函数,那么通过基类指针删除派生类对象时,只会调用基类的析构函数,导致派生类的资源未被正确释放。因此,基类的析构函数应声明为虚函数。
示例:
#include <iostream>

最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



