当前位置:  开发笔记 > 编程语言 > 正文

C++头文件,代码分离

如何解决《C++头文件,代码分离》经验,为你挑选了2个好方法。

我是C++的新手,我有一些关于代码分离的一般问题.我目前在一个文件中构建了一个小应用程序.我现在想要做的是将它转换为单独的文件,使它们包含类似的代码或诸如此类的东西.我现在真正的问题是,我怎么知道如何分开事物?代码应该分开的隐形边际是什么?

另外,头文件有什么意义?它是否转发声明方法和类,以便在编译期间链接器包含它们之前我可以在我的代码中使用它们?

对方法或最佳实践的任何见解都会很棒,谢谢!



1> Martin York..:

头文件应包含类和函数声明.

源文件包含类和函数定义.

标准做法(即更容易阅读)每个头文件有一个声明,每个源文件有一个定义,但对于小的(读简单助手)对象,有时你会将它们与相关的更实质的对象组合在一起.

示例:类菜单

Menu.h:     Contains the Menu declaration.
Menu.cpp:   Contains the Menu definition.

头文件包含声明的原因是,您可以从多个源文件中包含它们,因此每个源文件对每个类和函数具有完全相同的定义.

用这种方式考虑:
如果你没有头文件,那么你需要在每个源文件中都有类和/或函数声明(没有)定义,这意味着每个文件中都有相同声明的副本.因此,如果修改类,则需要在每个文件中进行相同的修改.通过使用头文件,您可以在一个地方声明,因此只需要修改一个对象.



2> Johannes Sch..:

首先,除了需要的文件之外,你不应该把任何东西放到任何其他文件不需要的标题中.然后,让我们在下面定义我们需要的东西.

翻译单位

翻译单元是正在编译的当前代码,以及由其直接或间接包含的所有代码.一个翻译单元转换为一个.o/.obj文件.

程序

这就是你的所有.o/.obj文件链接在一起形成一个二进制文件,可以执行以形成一个进程.

拥有不同翻译单位的要点是什么?

    减少依赖关系,这样,如果更改一个类的一个方法,则不必重新编译程序的所有代码,而只需重新编译受影响的翻译单元.一个

    通过具有翻译单元本地名称来减少可能的名称冲突,其他翻译单元在将它们链接在一起时不可见.

现在,您如何将代码拆分为不同的翻译单元?答案是没有"所以你这样做!",但你必须根据具体情况考虑它.通常很清楚,因为你有不同的类,可以而且应该放在不同的翻译单元中:

foo.hpp:

/* Only declaration of class foo we define below. Note that a declaration
 * is not a definition. But a definition is always also a declaration */
class foo;

/* definition of a class foo. the same class definition can appear 
   in multiple translation units provided that each definition is the same  
   basicially, but only once per translation unit. This too is called the  
   "One Definition Rule" (ODR). */
class foo {
    /* declaration of a member function doit */
    void doit();

    /* definition of an data-member age */
    int age;
};

声明一些自由函数和对象:

/* if you have translation unit non-local (with so-called extern linkage)  
   names, you declare them here, so other translation units can include  
   your file "foo.hpp" and use them. */
void getTheAnswer();

/* to avoid that the following is a definition of a object, you put "extern"  
   in front of it. */
extern int answerCheat;

foo.cpp:

/* include the header of it */
#include "foo.hpp"

/* definition of the member function doit */
void foo::doit() {
    /* ... */
}

/* definition of a translation unit local name. preferred way in c++. */
namespace {
    void help() {
        /* ... */
    }
}

void getTheAnswer() {
    /* let's call our helper function */
    help();
    /* ... */
}

/* define answerCheat. non-const objects are translation unit nonlocal  
   by default */
int answerCheat = 42;

bar.hpp:

/* so, this is the same as above, just with other classes/files... */
class bar {
public:
    bar(); /* constructor */
}; 

bar.cpp:

/* we need the foo.hpp file, which declares getTheAnswer() */
#include "foo.hpp"
#include "bar.hpp"

bar::bar() {
    /* make use of getTheAnswer() */
    getTheAnswer();
}

请注意,匿名命名空间(如上所示)中的名称不会发生冲突,因为它们似乎是本地翻译单元.实际上他们不是,他们只是有独特的名字,所以他们不会发生冲突.如果你真的想(没有理由)翻译单元本地名称(例如因为与c的兼容性,所以C代码可以调用你的函数)你可以这样做:

static void help() { 
    /* .... */
}

ODR还说你不能在一个程序中有任何对象或非内联函数的多个定义(类是类型,而不是对象,所以它不适用于它们).因此,您必须注意不要将非内联函数放入标题中,或者不要放置像"int foo"这样的对象.在标题中.这将导致链接器错误,然后链接器尝试将包括这些头的转换单元链接在一起.

我希望我能帮助你一点.现在这是一个很长的答案,某些地方确实存在错误.我知道翻译单元严格地以另一种方式定义(预处理器的输出).但我认为将上述内容纳入其中并不会增加很大的价值,而且会让事情变得混乱.如果你发现真正的错误,请随时打我

推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有