面试题答案
一键面试类的继承实现
在C++中,通过关键字public
、protected
、private
来定义继承方式,子类继承父类语法如下:
class Parent {
// 成员
};
class Child : public Parent {
// 新增成员
};
public
继承使得父类的public
和protected
成员在子类中保持原访问属性;protected
继承会让父类的public
和protected
成员在子类中变为protected
;private
继承使父类的public
和protected
成员在子类中变为private
。
多态性实现
- 编译时多态:通过函数重载和模板实现。函数重载是指在同一作用域内,多个函数可以具有相同名称但参数列表不同。模板则是一种通用的编程机制,允许编写参数化类型的代码。
// 函数重载示例 void func(int a) { /* 实现 */ } void func(double a) { /* 实现 */ } // 模板示例 template <typename T> T add(T a, T b) { return a + b; }
- 运行时多态:依赖虚函数和指针或引用实现。当通过基类指针或引用调用虚函数时,实际调用的函数版本取决于指针或引用所指向对象的实际类型。
虚函数作用
虚函数允许在子类中被重写,以实现不同的行为。基类中声明虚函数使用virtual
关键字。
class Shape {
public:
virtual double area() { return 0.0; }
};
class Circle : public Shape {
public:
double area() override { /* 圆面积计算 */ }
};
class Rectangle : public Shape {
public:
double area() override { /* 矩形面积计算 */ }
};
通过基类指针或引用调用area
函数时,会根据实际对象类型调用相应子类的area
函数,实现运行时多态。
纯虚函数作用
纯虚函数没有函数体,在基类中定义为virtual 返回类型 函数名(参数列表)=0;
。包含纯虚函数的类是抽象类,不能实例化对象。
class Shape {
public:
virtual double area() = 0;
};
class Circle : public Shape {
public:
double area() override { /* 圆面积计算 */ }
};
纯虚函数强制子类必须重写该函数,为多态提供了统一的接口规范。
虚析构函数作用
虚析构函数确保在通过基类指针删除对象时,能正确调用子类的析构函数,防止内存泄漏。
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {
public:
~Derived() {}
};
如果Base
的析构函数不是虚函数,当delete
一个指向Derived
对象的Base
指针时,只会调用Base
的析构函数,而不会调用Derived
的析构函数。
运行时多态和编译时多态区别
- 运行时多态:在运行期间根据对象实际类型决定调用哪个函数版本,依赖虚函数和指针或引用,开销相对较大,因为需要通过虚函数表查找函数地址。
- 编译时多态:在编译期间根据函数参数类型和模板参数决定调用哪个函数版本,通过函数重载和模板实现,效率高,因为编译器在编译时就确定了调用的函数。