在刚开始写 Qt 或 C++ 的时候,很多人都会被两个符号绕晕:
::.看起来都像是在"找某个东西",但它们的用法完全不一样。
如果这个点没搞清楚,后面看代码时会特别容易乱。
比如下面这些写法:
cppErrorHandler::instance() msgBox.setIcon(icon) QMessageBox::Information QApplication::quit()很多初学者一眼看过去,感觉都是"调东西",但其实它们背后的逻辑并不一样。
1. :: 是"通过类去找",. 是"通过对象去找"
这句话可以先背下来,因为后面很多判断都靠它。
::表示:我不是通过某个具体对象来访问,而是直接通过"类名"去找某个成员。
.表示:我手里已经有一个具体对象了,我要通过这个对象去调用它自己的成员。
这两个的区别,你可以简单理解成:
::更像是在说:"去这个类里面找".更像是在说:"让这个对象自己去做"
这是理解它们的总开关。
2. :: 是干什么的?它表示"属于某个类的"
先看这个例子:
cpp
ErrorHandler& ErrorHandler::instance()
{
static ErrorHandler instance;
return instance;
}
这里的:ErrorHandler::instance
意思就是:这个 instance 函数,是 ErrorHandler 这个类里面的函数。
因为现在是在类外面写函数实现,所以必须告诉编译器:
"我现在写的这个函数,属于哪个类。"
如果你只写:
cpp
ErrorHandler& instance()
编译器会觉得这是一个普通的全局函数,而不是 ErrorHandler 类的成员函数。
所以这里必须写成:
cpp
ErrorHandler& ErrorHandler::instance()
这就是 :: 的第一种常见用法:
用法一:在类外定义成员函数时,说明"这个函数属于谁"
再看这一段:
cpp
void ErrorHandler::handlerError(ErrorType type, ErrorLevel level, const QString &message, QWidget *parent)
这里同样是一个意思:
handlerError这个函数- 不是随便写的独立函数
- 它是
ErrorHandler类里的成员函数
所以也要用:ErrorHandler::来说明归属。
3. . 是什么:通过"对象"去调用
再看另一类写法:
cpp
msgBox.setIcon(icon);
msgBox.setText(message);
msgBox.exec();
这里的 msgBox 不是类名,而是前面创建出来的一个具体对象:
cpp
QMessageBox msgBox(parent);
既然 msgBox 已经是一个真正存在的对象了,那么后面要设置图标、设置文字、执行弹窗,就应该通过它自己去调用函数,所以这里用的是 .。
这时候你可以把 . 理解成:"这个对象自己的"
比如:
msgBox.setIcon(icon):让msgBox这个对象设置图标msgBox.setText(message):让msgBox这个对象设置显示文字msgBox.exec():让msgBox这个对象执行显示
所以 . 的核心很简单:手里已经有对象了,就用 .。
4. 为什么代码里会同时出现 :: 和 .
这是初学者最容易懵的地方。比如这种写法:
cpp
ErrorHandler::instance().logError(...)
看起来一行里既有 ::,又有 `.``,很容易乱。其实只要分两步看就很清楚了:
第一步:ErrorHandler::instance()
这里是通过类名 ErrorHandler 去拿那个全局唯一的对象,所以用 ::。
第二步:.logError(...)
因为前面 instance() 已经返回了一个具体对象,所以现在是在用这个对象去调用它的成员函数,因此这里要用 .。
也就是说,这一整句其实可以翻译成:
先从 ErrorHandler 类里拿到那个对象,再让这个对象去执行 logError。
这样一拆开,就不乱了。
5. 一句最通俗的总结
如果用一句最接地气的话来概括:
:: 是"去类里找",. 是"让对象自己做"。
在代码里:
ErrorHandler::instance():去类里拿对象QMessageBox::Information:去类里拿固定选项msgBox.setText(message):让对象自己设置内容msgBox.exec():让对象自己执行显示
把这个逻辑想清楚之后,再看 Qt 代码就不会觉得一团乱了。