最近在开发的过程中,涉及到多个目录下,都由相同文件名和类名的单例,但是调用的时候编译器却知道调用哪个,所以学习了下,做个笔记。
DataInteraction *DataInteraction::instance()
{static DataInteraction instance;return &instance;
}
这段代码是一个实现单例模式的函数,旨在保证一个类只有一个实例,并提供一个全局访问点。这个函数返回一个指向静态局部变量`instance`的指针。无论在多少个不同的源文件中调用这个函数,只要这些源文件链接到同一个可执行文件中,并且`DataInteraction`类的定义是相同的,这个函数将始终返回相同对象的地址。
然而,如果在不同的目录下有相同的这段代码,并且它们被编译成不同的库或者可执行文件,每个库或可执行文件将拥有其自己的`DataInteraction`实例。换句话说,每个动态链接库(DLL)或者每个可执行文件将拥有自己的`instance`静态局部变量。在这种情况下,不同的库或可执行文件之间的`DataInteraction`实例是独立的,并且不会混淆。
简单来说,如果在不同的子目录下创建了相同名字的文件`DataInteraction.cpp`和`DataInteraction.h`,并且这些文件中都包含了相同的单例实现代码,那么每个子目录中的`DataInteraction`都会成为各自子目录的局部单例。当在其他地方引入这些头文件时,实际上在使用相应子目录下的`DataInteraction`单例。
如果创建了多个这样的单例,每个单例都会在系统中存在一个实例。换句话说,每个单例的作用域仅限于创建它的子目录及其包含的源文件,不同子目录下的单例互不干扰,且系统中可能存在多个不同的`DataInteraction`实例。
系统在链接时会根据文件路径或命名空间来区分不同的实体。假设有以下结构:
Directory1/DataInteraction.cppDataInteraction.h
Directory2/DataInteraction.cppDataInteraction.h
在这种情况下,编译器会将每个`DataInteraction.cpp`编译为一个对象文件,并将其与相应的头文件一起编译。然后链接器将这些对象文件合并为一个可执行文件或库。由于文件位于不同的目录中,链接器能够区分它们,并且在链接时为每个目录创建相应的符号表。因此,当在其他地方引入`DataInteraction.h`时,编译器会根据当前上下文来选择相应目录下的实现。
如果在不同的目录中有相同名字的文件,并且它们被编译为不同的库,那么链接器将会将这些库中的符号分别保留,并且在链接时根据需要选择正确的符号。这样,系统就能够区分不同目录下的实例,并且不会混淆它们。