面试题答案
一键面试指针作用
通过Base*
指针指向Derived
对象,利用了C++的多态性。该指针允许在运行时根据实际指向的对象类型来决定调用哪个版本的func
函数。如果指向Base
对象,则调用Base
类的func
函数;若指向Derived
对象,就调用Derived
类重写的func
函数。
内存管理问题
- 对象创建与释放不匹配:如果通过
new
在堆上创建Derived
对象,并用Base*
指针指向它,释放时若使用delete Base*
,而Base
类的析构函数不是虚函数,那么只会调用Base
类的析构函数,Derived
类的析构函数不会被调用,可能导致Derived
类中分配的资源无法释放,造成内存泄漏。
代码示例
#include <iostream>
class Base {
public:
virtual void func() {
std::cout << "Base::func()" << std::endl;
}
// 为避免内存泄漏,基类析构函数应设为虚函数
virtual ~Base() {
std::cout << "Base::~Base()" << std::endl;
}
};
class Derived : public Base {
public:
void func() override {
std::cout << "Derived::func()" << std::endl;
}
~Derived() override {
std::cout << "Derived::~Derived()" << std::endl;
}
};
int main() {
Base* ptr = new Derived();
ptr->func();
delete ptr;
return 0;
}
避免内存泄漏的方法
- 虚析构函数:在
Base
类中定义虚析构函数。这样,当通过Base*
指针删除对象时,会先调用Derived
类的析构函数,再调用Base
类的析构函数,确保所有资源都被正确释放。如上述代码中Base
类的虚析构函数~Base()
。 - 智能指针:使用智能指针(如
std::unique_ptr
或std::shared_ptr
)来管理对象的生命周期。智能指针会在其作用域结束时自动释放所指向的对象,减少手动管理内存的错误。例如:
#include <iostream>
#include <memory>
class Base {
public:
virtual void func() {
std::cout << "Base::func()" << std::endl;
}
virtual ~Base() {
std::cout << "Base::~Base()" << std::endl;
}
};
class Derived : public Base {
public:
void func() override {
std::cout << "Derived::func()" << std::endl;
}
~Derived() override {
std::cout << "Derived::~Derived()" << std::endl;
}
};
int main() {
std::unique_ptr<Base> ptr = std::make_unique<Derived>();
ptr->func();
return 0;
}
在这个例子中,std::unique_ptr
会在离开作用域时自动调用Derived
对象的析构函数,从而避免内存泄漏。