C++ Qt实战技巧面试题
1. 如何优化Qt应用程序的性能?
答案:
- UI性能优化减少不必要的重绘使用双缓冲绘制避免在paintEvent中创建对象使用QPixmap缓存复杂绘制
void MyWidget::paintEvent(QPaintEvent* event) {
static QPixmap cache;
if (cache.isNull()) {
cache = QPixmap(size());
QPainter p(&cache);
// 复杂绘制
}
QPainter painter(this);
painter.drawPixmap(0, 0, cache);
}
- 内存优化使用对象池及时释放大对象使用隐式共享容器避免内存泄漏
- 多线程优化耗时操作放到工作线程使用线程池避免过多线程
- 信号槽优化减少不必要的连接使用DirectConnection(同线程)避免在槽函数中做耗时操作
2. 如何处理Qt中的内存泄漏?
答案:
- 常见原因没有指定父对象循环引用事件过滤器未移除定时器未停止
- 检测工具Valgrind(Linux)Visual Leak Detector(Windows)Qt Creator的内存分析器
- 最佳实践
// 好:指定父对象
QLabel* label = new QLabel("Text", this);
// 好:使用智能指针
QScopedPointer<QLabel> label(new QLabel("Text"));
// 注意:信号槽连接
connect(obj, &QObject::destroyed, this, [=]() {
// obj已销毁,不要访问
});
// 注意:定时器
QTimer* timer = new QTimer(this);
connect(this, &QObject::destroyed, timer, &QTimer::stop);
- deleteLater的使用
// 安全删除对象 obj->deleteLater(); // 在事件循环中删除 // 不要这样 delete obj; // 可能在信号处理中导致问题
3. 如何实现单例模式的Qt类?
答案:
- 线程安全的单例
class Singleton : public QObject {
Q_OBJECT
private:
Singleton(QObject* parent = nullptr) : QObject(parent) {}
public:
static Singleton& instance() {
static Singleton instance;
return instance;
}
// 禁止拷贝
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
- 带参数的单例
class ConfigManager : public QObject {
Q_OBJECT
private:
explicit ConfigManager(const QString& configFile) {
loadConfig(configFile);
}
public:
static ConfigManager& instance(const QString& configFile = "") {
static ConfigManager* inst = nullptr;
static QMutex mutex;
if (!inst) {
QMutexLocker locker(&mutex);
if (!inst) {
inst = new ConfigManager(configFile);
}
}
return *inst;
}
};
4. 如何实现Qt应用程序的日志系统?
答案:
- 使用qDebug系统
// 自定义消息处理
void messageHandler(QtMsgType type, const QMessageLogContext& context,
const QString& msg) {
QString txt;
switch (type) {
case QtDebugMsg:
txt = QString("Debug: %1").arg(msg);
break;
case QtWarningMsg:
txt = QString("Warning: %1").arg(msg);
break;
case QtCriticalMsg:
txt = QString("Critical: %1").arg(msg);
break;
case QtFatalMsg:
txt = QString("Fatal: %1").arg(msg);
break;
}
// 输出到文件
QFile file("log.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Append)) {
QTextStream stream(&file);
stream << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")
<< " " << txt << endl;
}
}
// 安装消息处理器
qInstallMessageHandler(messageHandler);
- 日志类封装
class Logger : public QObject {
Q_OBJECT
public:
static Logger& instance() {
static Logger logger;
return logger;
}
void log(const QString& msg, QtMsgType type = QtDebugMsg) {
QString logMsg = QString("[%1] %2")
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
.arg(msg);
emit logMessage(logMsg);
writeToFile(logMsg);
}
signals:
void logMessage(const QString& msg);
private:
void writeToFile(const QString& msg) {
// 写入文件
}
};
// 使用
Logger::instance().log("Application started");
5. 如何实现Qt应用程序的配置管理?
答案:
- 使用QSettings
// 写入配置
QSettings settings("MyCompany", "MyApp");
settings.setValue("window/size", size());
settings.setValue("window/pos", pos());
settings.setValue("user/name", "Alice");
// 读取配置
QSettings settings("MyCompany", "MyApp");
QSize size = settings.value("window/size", QSize(800, 600)).toSize();
QPoint pos = settings.value("window/pos", QPoint(100, 100)).toPoint();
QString name = settings.value("user/name", "").toString();
- 配置管理类
class Config {
public:
static Config& instance() {
static Config config;
return config;
}
void save() {
QSettings settings("MyCompany", "MyApp");
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
C++ 常考面试题总结 文章被收录于专栏
本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.
查看10道真题和解析