Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ g++;使用旧代码的旧对象文件链接良好_C++_Linker_G++ - Fatal编程技术网

C++ g++;使用旧代码的旧对象文件链接良好

C++ g++;使用旧代码的旧对象文件链接良好,c++,linker,g++,C++,Linker,G++,base1.h base2.cpp class base2 { public: virtual void base2fun(); }; class base2 { public: int padding; virtual void base22fun(); virtual void base2fun(); }; 导出的.cpp #include "base1.h" #include "base2.h" class derived : public base1, pu

base1.h

base2.cpp

class base2
{
 public:


  virtual void base2fun();
};
class base2
{
 public:
  int padding;
  virtual void base22fun();
  virtual void base2fun();
};
导出的.cpp

#include "base1.h"
#include "base2.h"

class derived : public base1, public base2
{
 public:
  virtual void base1fun();
  virtual void base2fun();
};
main.cpp

#include "derived.h"

static derived d;
base1& b1=d;
base2& b2=d;
#include "base2.h"
#include "iostream"

using namespace std;
void base2::base22fun()
{
  cout<<"inside base2::base22fun()"<<endl;
}

void base2::base2fun()
{
  cout<<"inside base2::base2fun()"<<endl;
}
base2.cpp

class base2
{
 public:


  virtual void base2fun();
};
class base2
{
 public:
  int padding;
  virtual void base22fun();
  virtual void base2fun();
};
#包括“base2.h”
#包括“iostream”
使用名称空间std;
void base2::base22fun()
{

无法对象“static-derived d;”是在运行exe时创建的。它与complie和link无关。因此它起作用了。

首先,学会使用
生成文件。
。这样,你就不必键入太多内容了

只要存在所需的全局符号(在本例中是类的构造函数,可能还有类的vtable),链接器就会成功。重新编译后,对象会占用额外的空间,因此它会覆盖另一个变量。如果要添加:

#include "base2.h"
#include "iostream"
using namespace std;

int main()
{
  extern base2& b2;
  cout<<b2.padding;
 return 0;
}
在构造函数中
静态派生d;
-且未初始化
填充
之后,您将看到
填充
打印为42


所有这些都是“未定义的行为”。它被允许以任何看似合理的方式失败——格式化硬盘、发动第三次世界大战或“有微妙副作用的工作”。使用设置了相关依赖项的
makefile
,以便在
base2.h
发生更改时自动重新编译
对象。cpp
是正确的做法。

这为什么令人惊讶?为什么您认为链接器无法链接在不同时间编译的对象文件?@user657267global.o中的de>派生d
是根据
base2
的旧定义,因此在修改
base2
时它不应该工作。如果我有错误,请更正,但编译器分配的空间“更小”因为编译器在编译时分配大小。空间是在exe启动时分配的。不。检查生成的程序集文件(-S在gcc/clang中)-它将有类似于
d:.0 8
(或4)-使用修改过的对象重新编译,以及8(或4)将更改为12或16或其他。除非您误解了我的意思,否则我很抱歉,因为还不完全清楚-对象的大小是在编译时确定的-它占用的实际内存当然是在加载可执行文件时分配的。但关键是大小是在编译时确定的,而不是在运行时确定的我,对于对象。抱歉,我误解了。即使我试图从main调用
base2::base22fun
,它仍然有效。这是否有效,因为
base2
只有一个vtable?谢谢!是的,应该只有一个vtable(对于给定的类)
class base2
{
 public:
  int padding;
  virtual void base22fun();
  virtual void base2fun();
};
#include "base2.h"
#include "iostream"

using namespace std;
void base2::base22fun()
{
  cout<<"inside base2::base22fun()"<<endl;
}

void base2::base2fun()
{
  cout<<"inside base2::base2fun()"<<endl;
}
#include "base2.h"
#include "iostream"
using namespace std;

int main()
{
  extern base2& b2;
  cout<<b2.padding;
 return 0;
}
static int x = 42;