【发布时间】:2020-02-05 09:00:49
【问题描述】:
我在 Eclipse 中有一个大项目,其中包含多个嵌套项目。这些嵌套项目中的每一个都位于一个单独的文件夹中,并单独编译和链接。最后,它们每个都输出一个单独的静态库。然后很少有与这些静态库链接的可执行文件。在其中两个项目中,我有两个具有相同名称和相同构造函数参数的类,但它们具有不同的实现和不同的额外成员。两个类都在同一个命名空间中。编译每个项目后,我使用他们为单独的可执行文件创建的静态库。每个可执行文件都链接到正确的类,它们不会混合实现。一切似乎都很好。
问题是当我编译其中一个类时,编译器给我一个错误,我没有初始化一些实际上属于另一个类的成员变量。在编译期间,这些类不能相互访问——它们不包含另一个类,或者它们不包含标题,然后包含另一个。它们位于不同的项目中,位于不同的文件夹中,并且分别编译。那么,在编译第一个类时,编译器如何以某种方式查找第二个类的定义并给我一个错误,即我没有从中初始化成员?由于我使用的是 Eclipse,并且我的项目结构是这样的: Main C++ Project(未编译)将其他 C++ 项目作为嵌套项目(单独编译)保存在其中 - 这可能与 Eclipse 有关吗?
我是否违反了单一定义规则,因为我的类位于不同的项目中,并且它们是在不同的编译中编译的,只有一些通用的头文件,它们之间没有其他连接?如果是这样,编译器怎么可能捕捉到这样的问题,但它仍然能够获得正确的类定义?因为可以肯定它做对了,一切正常。
所以我的问题是编译器给我的警告,因为我必须在发送代码之前清除所有编译警告。代码本身运行良好。
最好的问候
=== 评论后更新===
首先,对不清楚的地方表示歉意。 这是整个项目结构的图像(我显然已经更改了名称:)):
我有 MainProject 项目,它充当其他项目的容器。我不建造它。在 nested1 我有制作静态库的项目,然后我将其与 Executable1 和 Executable2 链接。在 nested2 我有其他项目再次制作静态库,然后我将其与 Executable3 链接。
我在nested1 和nested2 中都有MyFooBar 类。这是他们两个的代码
// nested1/StaticLib5/MyFooBar.hpp
namespace foo
{
namespace bar
{
class MyFooBar : public FooBar
{
public:
MyFooBar(int a, int b, double c);
// Getters and Setters
// Other user-defined functions
private:
int memA;
int memB;
double memC;
int memDiff1;
};
}
}
// nested2/StaticLib9/MyFooBar.hpp
namespace foo
{
namespace bar
{
class MyFooBar : public FooBar
{
public:
MyFooBar(int a, int b, double c);
// Getters and Setters
// Other user-defined functions
private:
int memA;
int memB;
double memC;
int memDiff2;
char memDiff3;
};
}
}
// nested1/StaticLib5/MyFooBar.cpp
namespace foo
{
namespace bar
{
MyFooBar::MyFooBar(int a, int b, double c) :
memA{a}, memB{b}, memC{c}, memDiff1{0}
{
}
}
}
// nested2/StaticLib9/MyFooBar.cpp
namespace foo
{
namespace bar
{
MyFooBar::MyFooBar(int a, int b, double c) :
memA{a}, memB{b}, memC{c}, memDiff2{0}, memDiff3{0}
{
}
}
}
Executable1 和 Executable2 不使用 nested2 中的任何库。 Executable3 使用唯一的静态库 StaticLib1 nested1。
没有一个可执行文件链接到 StaticLib5 和 StaticLib9。此外,在链接可执行文件期间我没有收到错误,在编译任何 MyFooBar 类时都会收到警告。警告说:
Member memDiff2 was not initialized in this constructor
这两个类唯一可能共有的是一个标题,其中我有一个类前向声明和一些 typedef,我不在类本身中使用它们。
class MyFooBar;
typedef ListWidget* MyFooBarPtr;
typedef std::vector< MyFooBarPtr > MyFooBarVec;
typedef MyFooBarVec* MyFooBarVecPtr;
【问题讨论】:
-
文字过多。没有代码。这是一个糟糕的问题。
-
同一个命名空间中的两个同名类在链接发生时会发生冲突,是的。
-
为什么现在这样有效,取决于您的项目特有的许多变量。有一天它可以停止工作。所以你最好把它修好。
-
@RSahu:我添加了示例代码。
-
@Chad:我不会同时链接他们两个。
标签: c++ class namespaces eclipse-cdt