我知道可以在多个文件中执行类实现(是的,我知道这是个坏主意),但我想知道是否可以在单独的文件中编写类定义而不会出现重定义错误(也许一些技巧,或者......)
答案 0 :(得分:4)
不,不是同一个班级,但为什么会这样?
你可以在两个不同的头文件中在同一个命名空间中定义两个具有相同名称的类(相同的签名!它实际上是同一个类,只是以两种方式定义)并编译你的程序,如果你的源代码文件不包含两个标头。您的应用程序甚至可以链接,但是在运行时,事情将无法正常工作(它将是未定义的行为!),除非类是相同的。
有关更正式的解释,请参阅Charles Bailey's answer。
编辑:
如果您想要的是由多个文件定义的单个类,为了(例如)向您的类添加一些自动生成的函数,您可以#include
在中间的辅助文件你的班级。
/* automatically generated file - autofile.gen.h */
void f1( ) { /* ... */ }
void f2( ) { /* ... */ }
void f3( ) { /* ... */ }
/* ... */
/* your header file with your class to be expanded */
class C
{
/* ... */
#include "autofile.gen.h"
/* ... */
};
答案 1 :(得分:3)
不像C#中的partial
关键字那样干净整洁,但是,您可以将您的类拆分为多个头文件:
class MyClass
{
#include "my_class_aspect1.h"
#include "my_class_aspect2.h"
#include "my_class_aspect3.h"
};
#include "my_class_aspect1.inl"
#include "my_class_aspect2.inl"
#include "my_class_aspect3.inl"
答案 2 :(得分:2)
好吧......
如果您有1个头文件,如下所示
ClassDef1.h:
class ClassDef
{
protected:
// blah, etc.
public:
// more blah
和另一个如下
ClassDef2.h:
public:
// Yet more blah.
};
该课程将在2个文件中有效定义。
除了那种诡计...... AFAIK,不,你不能。
答案 3 :(得分:1)
是。通常,人们将声明部分放在.h文件中,然后将函数体实现放在.cpp文件中 将声明放在.h文件中,然后在任意数量的文件中实现,但在每个文件中包含.h。
但是,你不能在多个文件中实现相同的东西
答案 4 :(得分:1)
是的,你可以。每个定义必须在单独的翻译单元中进行,但对多个定义有很多限制。
每个定义必须由相同的令牌序列组成,并且在每个定义中,对应的名称必须引用同一个实体(或类本身定义中的实体)。
有关详细信息,请参见ISO 14882:2003的3.2 [basic.def.odr] / 5。
答案 5 :(得分:1)
我知道这是一篇迟到的帖子,但是一位朋友刚问了我一个类似的问题,所以我想我会发表讨论:
根据我的理解,你想做ThinkingStiff,在C ++中是不可能的。我认为你想要在C#中使用类似“部分类”的东西。
请记住,.NET中的“partial class”是必要的,因此您不必将整个实现放在一个大的源文件中。与C ++不同,.NET不允许您的实现与声明分开,因此需要“部分类”。所以,Rafid它不是一个很好的功能,它是一个必要的功能,以及轮子恕我直言的重新发明。
如果您的类定义太大,则需要将其拆分为多个源文件,然后它可能会拆分为较小的解耦类,而主类可以使用介体设计模式将他们联系在一起。
如果您希望隐藏私人成员,例如在开发商业图书馆并且您不希望泄露知识产权(或暗示该影响)时,您可以使用纯抽象类。这样,标题中的所有内容都是简单类,包含所有公共定义(API)和用于创建实例的工厂函数。所有实现细节都在您的源文件中。
另一种替代方法与上面类似,但使用普通类(不是纯虚拟类),但仍然只公开公共接口。在您的源文件中,您可以在无名空间中完成所有工作,必要时可以在您的类定义中包含朋友函数等。再多做一些工作,但是一种合理的技术。
我加粗您可能想要查找并在解决问题时考虑的事项。
答案 6 :(得分:0)
这是C#的一个很好的功能,但不幸的是它在C ++中不受支持。
答案 7 :(得分:0)
也许像policy based design这样的伎俩会成功吗?多重继承为您提供了以其他语言无法创建的方式编写类的可能性。当然还有与MI有关的陷阱,所以要确保你知道自己在做什么。
答案 8 :(得分:0)
简短的回答是肯定的,这是可能的。正确的答案是否定的,你甚至不应该考虑这样做(如果你忽视该指令,你将被其他程序员鞭打)。
答案 9 :(得分:-1)
您可以将成员函数的定义拆分为其他转换单元,但不能拆分类本身。要做到这一点,你需要做预处理器技巧。
// header file with function declarations
class C {
public:
void f(int foo, int bar);
int g();
};
// this goes into a seperate file
void C::f(int foo, int bar) {
// code ...
}
// this in yet another
void C::g() {
// code ...
}
答案 10 :(得分:-1)
你必须有一个理由想要在两个标题之间进行分割,所以我的猜测是你真的想要两个连接起来形成单个(第三个)类的组件的类。