g++可以很好地链接带有旧代码的旧对象文件
g++ links fine with old object files with old code
base1.h
void base2::base22fun()
{
cout<<"inside base2::base22fun()"<<endl;
}
base1.cpp
#include "base1.h"
#include "iostream"
using namespace std;
void base1::base1fun()
{
cout<<"inside base1::base1fun()"<<endl;
}
base2.h
class base2
{
public:
virtual void base2fun();
};
base2.cpp
#include "base2.h"
#include "iostream"
using namespace std;
void base2::base2fun()
{
cout<<"inside base2::base2fun()"<<endl;
}
衍生.h
#include "base1.h"
#include "base2.h"
class derived : public base1, public base2
{
public:
virtual void base1fun();
virtual void base2fun();
};
导出.cpp
#include "derived.h"
#include "iostream"
using namespace std;
void derived::base1fun()
{
cout<<"inside derived::base1fun"<<endl;
}
void derived::base2fun()
{
cout<<"inside derived::base2fun"<<endl;
}
global.cpp
#include "derived.h"
static derived d;
base1& b1=d;
base2& b2=d;
main.cpp
#include "base2.h"
#include "iostream"
using namespace std;
int main()
{
extern base2& b2;
cout<<b2.base2fun();
return 0;
}
我使用g++ base1.cpp base2.cpp derived.cpp global.cpp main.cpp -c
生成了所有.cpp文件的对象文件
然后我把它们都联系起来,效果很好。
现在我修改base2.h base2.cpp和main.cpp如下
base2.h
class base2
{
public:
int padding;
virtual void base22fun();
virtual void base2fun();
};
base2.cpp
#include "base2.h"
#include "iostream"
using namespace std;
void base2::base22fun()
{
cout<<"inside base2::base22fun()"<<endl;
}
void base2::base2fun()
{
cout<<"inside base2::base2fun()"<<endl;
}
main.cpp
#include "base2.h"
#include "iostream"
using namespace std;
int main()
{
extern base2& b2;
cout<<b2.padding;
return 0;
}
然后我重新编译了base2.cpp、derived.cpp和main.cpp
我没有重新编译global.cpp,而是使用了旧的对象文件[global.o],g++链接了它们并执行了可执行文件。这怎么可能?
谢谢。
首先,学习使用makefile
。这样,你就不必打那么多。。。
只要存在所需的全局符号,链接器就会成功——在这种情况下,是类的构造函数,可能还有类的vtable。您的对象在重新编译后会占用额外的空间,因此它将覆盖另一个变量。如果要添加:
static int x = 42;
在static derived d;
-并且没有在构造函数中初始化padding
之后,您会看到padding
打印为42。
所有这些都是"未定义的行为"。它可以以任何看似合理的方式失败——格式化硬盘、发动第三次世界大战,或者"有微妙副作用的工作"。使用设置了相关依赖项的makefile
,以便在base2.h
发生更改时自动重新编译objects.cpp
,这将是正确的做法。
对象"static-derived;"是在运行exe时创建的。它与compile和link无关。所以它起了作用。
相关文章:
- 为什么我们不在下面给出的代码中使用指针来实例化C++的实体对象?
- 如果 iostream 对象不可复制,为什么以下代码是合法的?
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- 创建跨平台 C++ 触摸管理器.在 c++ 中传递 Objective-c 对象涉及代码
- 由于缺少类模板,NVCC 编译面向对象代码时出现问题
- 使用 jni 将返回带有模板的对象的 Java 代码转换为 c++
- 在 C++ 对象包装器中安全地包含 C 代码
- 在C++代码中搜索对象的实例化位置
- 使用.natvis文件可视化VS代码中的C++对象
- C++指向对象的指针堆数组中,如何将字符串传递给特定对象?有一些代码请看一下:
- C++ 被此代码与多态性、指针和对象切片混淆
- 从本机代码返回到托管代码会损坏返回的对象
- 如果用户尝试从 JS 调用对象的未定义函数C++则回调C++代码
- 在 boost::p ython 中的 python 对象中运行 python 代码
- 初始化不可移动对象数组:为什么这样的代码无法在 GCC 上编译?
- 一般函数中类的概括为基类创建对象代码
- C++模板的对象代码是否在可执行文件和动态库中重复?
- 我不想导出的函数的未记录代码对象警告
- 代码对象和可执行文件的区别
- 如何保持作为 SWIG shared_ptr传递给非托管代码的托管代码对象的活动状态?