面试题答案
一键面试- 单一继承场景
- 基类:
- 构造函数:负责分配系统级资源,如共享内存段的映射。例如:
- 基类:
class Base {
public:
Base() {
// 分配共享内存段映射的代码
// 假设这里有一个函数 mapSharedMemory 来进行映射
sharedMemory = mapSharedMemory();
}
~Base() {
// 释放共享内存段映射的代码
// 假设这里有一个函数 unmapSharedMemory 来进行解映射
unmapSharedMemory(sharedMemory);
}
private:
void* sharedMemory;
};
- **派生类**:
- **构造函数**:首先调用基类构造函数,然后初始化动态加载的插件模块资源。例如:
class Derived : public Base {
public:
Derived() {
// 调用基类构造函数后,初始化插件模块
plugin = loadPlugin();
}
~Derived() {
// 卸载插件模块
unloadPlugin(plugin);
}
private:
void* plugin;
};
- 多重继承场景
- 基类1(负责系统级资源):构造函数和析构函数与单一继承中的基类类似。
class Base1 {
public:
Base1() {
sharedMemory = mapSharedMemory();
}
~Base1() {
unmapSharedMemory(sharedMemory);
}
private:
void* sharedMemory;
};
- 基类2(负责其他资源,假设为数据库连接):构造函数分配资源,析构函数释放资源。
class Base2 {
public:
Base2() {
dbConnection = establishDBConnection();
}
~Base2() {
closeDBConnection(dbConnection);
}
private:
void* dbConnection;
};
- 派生类:构造函数按照声明顺序调用基类构造函数,然后初始化自己的插件模块资源。析构函数按构造函数相反顺序释放资源。
class Derived : public Base1, public Base2 {
public:
Derived() {
plugin = loadPlugin();
}
~Derived() {
unloadPlugin(plugin);
}
private:
void* plugin;
};
- 虚继承场景
- 虚基类(负责公共资源,如日志文件句柄):
- 构造函数:分配资源。
- 虚基类(负责公共资源,如日志文件句柄):
class VirtualBase {
public:
VirtualBase() {
logFile = openLogFile();
}
~VirtualBase() {
closeLogFile(logFile);
}
private:
FILE* logFile;
};
- 中间类1(继承虚基类并增加自己的资源,如网络套接字):
- 构造函数:调用虚基类构造函数,然后分配自己的资源。
class Intermediate1 : virtual public VirtualBase {
public:
Intermediate1() {
socket = createSocket();
}
~Intermediate1() {
closeSocket(socket);
}
private:
int socket;
};
- 中间类2(继承虚基类并增加自己的资源,如文件描述符):
- 构造函数:调用虚基类构造函数,然后分配自己的资源。
class Intermediate2 : virtual public VirtualBase {
public:
Intermediate2() {
fileDescriptor = openFile();
}
~Intermediate2() {
closeFile(fileDescriptor);
}
private:
int fileDescriptor;
};
- 最终派生类:
- 构造函数:虽然虚基类构造函数会被中间类调用,但为了明确和一致性,在最终派生类构造函数初始化列表中也列出虚基类。然后调用中间类构造函数,最后初始化自己的插件模块资源。
class FinalDerived : public Intermediate1, public Intermediate2 {
public:
FinalDerived() : VirtualBase(), Intermediate1(), Intermediate2() {
plugin = loadPlugin();
}
~FinalDerived() {
unloadPlugin(plugin);
}
private:
void* plugin;
};
注意事项:
- 在多重继承和虚继承中,要明确构造函数和析构函数的调用顺序,避免资源泄漏和未定义行为。
- 虚继承时,虚基类的构造函数由最底层的派生类调用,以确保资源的正确初始化和唯一性。
- 所有资源分配和释放操作应确保异常安全性,例如在构造函数中,如果资源分配失败,应确保已分配的其他资源被正确释放。