gpt4 book ai didi

c++ - g++ 与旧代码的旧目标文件链接良好

转载 作者:行者123 更新时间:2023-11-28 02:14:44 24 4
gpt4 key购买 nike

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;
}

全局.cpp

#include "derived.h"

static derived d;
base1& b1=d;
base2& b2=d;

主要.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;
}

主要.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 是正确的做法。

关于c++ - g++ 与旧代码的旧目标文件链接良好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34350872/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com