我见过类似的问题,但他们仍然没有意义,我的猿类大脑。
这里有一个例子。如果我在名为bob.h
的头文件中声明了一个函数:void PrintSomething();
并且在.cpp
文件中声明了一个函数:void myclass::PrintSomething(){std::cout<<“hello”;}
。我在另一个.cpp
文件(例如frank.cpp
)中看到过这样的人,它只包含bob.h
头,它只有声明(里面没有代码),而不包含带有代码的.cpp
。但令我震惊的是,当他们调用frank.cpp
中的printSomething()
函数时,它使用了bob.cpp
中的代码并打印“hello”。怎么做?当我只包含了.h
文件时,它如何打印在.cpp
文件中添加的“hello”,而它只是一个声明,它对“hello”只字不提?我也看过编译过程和链接过程,但它就是不坚持。
如果我现在在我的frank.cpp
文件中说:void myclass::printsomething(){std::cout<<“bye”;}
并在我的main.cpp
中包含bob.h
文件,并调用printsomething()
函数,那么它会打印“hello”或“bye”吗?电脑是灵媒还是什么?这个概念是我在C++学习过程中没有掌握的一件事。
提前道谢。
当您包含bob.h
时,编译器就拥有了它需要知道的关于printSomething()
的一切,它只需要函数的声明。frank.cpp
不需要了解定义printSomething()
的bob.cpp
。
所有单独的cpp
文件都输出编译器生成的对象文件。在它们被粘在一起之前,它们本身并没有什么作用,这是连接者的责任。
链接器将获取所有对象文件并填充缺少的部分:
链接器对话:
嘿,我看到frank.obj
使用了printSomething()
,而我在该对象文件中看不到它的定义。
让我们检查其他对象文件。
在检查bob.obj
时,我可以看到它包含了printSomething()
的可用定义,让我们使用它。
这当然是简化的,但简而言之,这就是链接器的作用。
完成这些之后,您就得到了可用的可执行文件。
如果我现在在frank.cpp文件中说:void myclass::printsomething(){std::cout<<“bye”;}
并在我的main.cpp
中包含bob.h
文件,并调用printsomething()
函数,那么它会打印“hello”或“bye”吗?电脑是灵媒还是什么?
链接器会找到printsomething()
的两个定义,并会发出一个错误,它无法知道哪个定义是要选择的正确定义。