面试题答案
一键面试结合类模板和运行时多态的方法
- 类模板中包含虚函数:在类模板内部定义虚函数,使得不同实例化的类模板对象可以通过指针或引用实现运行时多态。例如:
template <typename T>
class Base {
public:
virtual void print() const = 0;
};
template <typename T>
class Derived : public Base<T> {
public:
void print() const override {
// 具体实现
}
};
然后可以这样使用:
Base<int>* ptr = new Derived<int>();
ptr->print();
delete ptr;
- 使用智能指针管理对象:为了避免内存泄漏,结合运行时多态时推荐使用智能指针,如
std::unique_ptr
或std::shared_ptr
。例如:
std::unique_ptr<Base<int>> ptr = std::make_unique<Derived<int>>();
ptr->print();
可能遇到的性能问题
- 虚函数表开销:每个包含虚函数的类都会有一个虚函数表(vtable),每个对象都有一个指向虚函数表的指针(vptr)。这会增加对象的大小,在内存紧张的场景下可能成为问题。
- 动态绑定开销:运行时多态通过动态绑定实现,在调用虚函数时,需要通过vptr找到对应的虚函数表,再找到具体的函数地址,这一过程有一定的时间开销。尤其是在频繁调用虚函数的循环中,性能影响更明显。
优化策略
- 减少对象大小:如果对象中有很多数据成员,可以考虑将部分数据成员提取到单独的类中,通过指针引用,以减少包含虚函数对象的大小。
- 内联虚函数:对于简单的虚函数,可以将其定义为内联函数,这样在编译时,编译器可能会将函数调用直接替换为函数体,减少动态绑定的开销。例如:
template <typename T>
class Base {
public:
virtual inline void print() const = 0;
};
- 避免不必要的虚函数调用:在性能敏感的代码段,尽量避免虚函数调用。可以将频繁调用的函数提取到非虚函数中,在虚函数中调用非虚函数。例如:
template <typename T>
class Base {
public:
virtual void complexOperation() {
commonNonVirtualPart();
// 其他虚函数特定的操作
}
private:
void commonNonVirtualPart() {
// 频繁执行的公共部分
}
};