订购#includes [英] Ordering of #includes

查看:74
本文介绍了订购#includes的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



来自VB,如果函数A想要调用函数B,那么我还没有真正理解如何使用C ++中的
,然后

函数B必须在

编译中的函数A之前,而#includes使用其他类中的类

依赖于其他人必须在之后相应的。


我有三个问题,如果可以的话,


1)当我创建MFC应用程序时一个对话框

类和一个应用程序类(由向导生成)

作为前四个文件(CMyDlg.h,CMyDlg.cpp,CMyApp.h

和CMyApp.cpp)我想添加另一个类,

CMyClass,我提到的四个向导生成的文件中的哪一个我要#include它包含它一般?而且我还要

必须包含CMyClass.cpp文件 - 或者如果没有,确实

它知道自动为
$ b选择这个文件$ b编译CMyClass函数的实现?


2)我在VC ++中经历过奇怪的行为.net 2002当我想要b $ b想要有一些#define语句很大程度上与我添加的额外课程有关,但是我的CMainDlg类在其.cpp文件中需要一个

位,以及

编译器只接受它,如果我把它们放在添加的

类的头文件中 - 如果它们之前是

怎么回事呢?所有#includes?如果你要构建一个

的应用程序,你通常应该如何订购和放置#include和

定义语句的一般规则是什么?

对话框和应用程序有两个主要的类

对象和很多其他对象,你想把它们保存在

单独的文件中吗?


3)某些类

可能要调用的全局函数应该在哪里,如果那些

全局函数想要引用对象,它们应该在哪里?那些是从不同的

文件中定义的类实例化的吗?

如果有人能给我一个,我会非常感激br />
这里的解释因为它开始让我迷惑一点

并且让我的项目布局有点乱,因为我只需要保留
移动它们直到编译器没有

得到'某某某某未被宣布''牛肉。


非常感谢

祝福
Ben

Hi,
Coming from VB, I''ve still not really grasped the way how
in C++ if function A wants to call function B, then
function B has to be before function A in the
compilation, and #includes that use the classes in others
rely on others have to be after them accordingly.

I''ve got three questions about this if I may,

1) When I create an MFC application by having a dialog
class and an application class (generated by the wizard)
as the first four files (CMyDlg.h, CMyDlg.cpp, CMyApp.h
and CMyApp.cpp) and I want to add another class,
CMyClass, which of the four wizard generated files I
mentioned should I #include it in normally? And do I also
have to include the CMyClass.cpp file - or if not, does
it know to pick this file up automatically for the
compilation of the implementation of CMyClass''s functions?

2) I experienced strange behavior in VC++.net 2002 when I
wanted to have some #define statements that largely
related to an extra class I added, but would be needed a
bit by my CMainDlg class in its .cpp file aswell, and the
compiler would only accept it if I put them in the added
class''s header file - how did it not work if they were
before all the #includes? What is the general rule for
how you should generally order and place the #include and
define statements if you are building an application that
has two main classes for the dialog and application
objects and lots of others, and you want to keep them in
separate files?

3) Where should global functions that some of the classes
might want to call be, and where should they be if those
global functions want to refer to objects that are
instantiated from classes that are defined in different
files?
I''d be very thankful if somebody could give me an
explanation here as it''s beginning to confuse me a bit
and making my project layout a bit messy as I just have
to keep moving them around till the compiler hasn''t
got ''so-and-so not declared'' beef.

Many thanks
Best wishes
Ben

推荐答案

Ben Taylor写道:
Ben Taylor wrote:

来自VB,如果函数A想要调用函数B,我还没有真正掌握如何在C ++中使用

函数B必须在
编译中的函数A之前,并且#includes使用其他人的课程
依赖他人必须相应地追随他们。


要记住的重要概念:


编译模型。

VB(和C#和Java)使用整个程序。编译模型。也就是说,

编译器(至少在逻辑上如果不是这样)会立即查看整个程序

(程序集,DLL等)。


C和C ++使用单个模块。编译模型。在这个模型中,

编译器一次只能看到一个模块,并且没有任何概念或知识

在任何其他模块中是什么。按照惯例,模块是.C或.CPP文件,

但实际上它是在命令上提供给编译器的任何文件

line - there'关于.cpp文件并没什么特别之处。而不是标题

文件。


声明与定义。


声明:声明:一个东西(类,函数,

对象等)存在的编译器。提供使用

事物所需的所有信息(即调用函数,引用对象等)。类似于

" interface"这个东西。


例子:函数原型是一个声明。


定义:提供有关编译器如何构建的详细信息

的事情。与先前声明不符的定义也是

被视为声明。类似于实施。这个东西。


例子:带有正文的函数头是一个定义。


在VB,C#和Java等语言中,声明中没有声明分离

。由于这些语言使用整个程序,编译

模型,编译器只需搜索程序的所有模块即可获得它所需要的任何声明。


在C和C ++中,由于编译器一次只能看到一个模块,所以它不能找到在一个模块中引用但定义为

in的东西的定义。另一个。您必须通过提供所引用的所有内容的定义来帮助它,即使它未在该特定模块中定义。通过

转换,你提供定义的方式是通过头文件,但

这只是一个惯例。

The One定义规则


在C和C ++中,有一个重要的规则:一个定义规则。另外

称为ODR。这表明一个东西(函数,类等)

必须在一个完整的程序中有一个单独的定义,或者结果是未定义的结果。请注意,'是一个单一的定义,而不是一个声明!

内联函数之类的内容存在漏洞,实际上可以在几个地方定义
。如果

这些定义实际上是不同的,那么程序的行为仍然是不确定的。

预处理


VB,C#,Java和类似的语言没有C / C ++那样的预处理器概念。预处理器将来自一个或多个文件的输入组合成令牌流,这是编译器适当消耗的。也就是说,编译器本身对文件或文件名确实一无所知

或命名约定 - 它只看到单个线性令牌流

预处理器耗材。


单遍


C和C ++编译器逻辑上通过源代码一次,

订单,从上到下。理论上,例如,C ++编译器可以通过来自预处理器的TCP套接字接收它的令牌流,理论上,它可以运行在
上。一个单独的机器。

现在,考虑到这些基础概念:

如果可能,我有三个问题,

1)当我创建一个MFC应用程序时,通过一个对话框类和一个应用程序类(由向导生成)
作为前四个文件(CMyDlg.h,CMyDlg.cpp,CMyApp) .h
和CMyApp.cpp)我想添加另一个类,CMyClass,我提到的四个向导生成的文件中的哪一个应该正常#include它?我是否还必须包含CMyClass.cpp文件 - 如果没有,它是否知道自动选择此文件以编译CMyClass函数的实现?


正常的MFC编程约定是生成两个新文件:

CMyClass.h和CMyClass.cpp。你将CMyClass的声明放在

头文件和.cpp文件中的定义中,然后将#include CMyClass.h放在

的适当位置(s )。例如,如果CMyDlg在它的'b
定义中使用CMyClass(假设CMyDlg有一个类型为CMyClass的数据成员),那么你就可以使用
#include CMyClass .h在CMyDlg.h中。如果CMyClass的声明只需要(例如)CMyApp的定义,那么你通常会在CMyApp.cpp中使用
#include CMyClass.h而不是在CMyApp.h中。请注意,常见的

MFC约定是#include stdafx.h中的所有内容,#include
其他头文件中的#include,以及#include StdAfx.h in all .cpp文件。这有点

模拟整个程序。编译模型,因为每个模块都包含

a声明程序中的所有内容,即使它不需要。

2)我在VC ++中经历过奇怪的行为.net 2002当我想要一些#define语句与我添加的额外类相关时,但是我的CMainDlg类需要在其.cpp文件中使用它,以及
编译器只会接受它,如果我把它们放在添加的
类的头文件中 - 如果它们在所有#includes之前它是如何工作的呢?如果要构建一个应用程序,对于对话框和应用程序有两个主要类,那么通常如何排序和放置#include和
定义语句的一般规则是什么? >对象和很多其他的,你想把它们保存在单独的文件中?


一般来说,你应该把东西(#define,定义,声明,

等)放在一个包含在正确位置的文件中(s) )。如果是东西,是一个

定义,它需要放在一个不会违反ODR的文件中。

例如,函数定义和类定义应放在

" cpp file",除非它们是内联的,在这种情况下它们应放在

"头文件中。 (因为内联定义必须在每个点都可见

它被引用)。

3)某些类的全局函数应该在哪里
可能想要调用be,如果那些全局函数想要引用从不同
文件中定义的类实例化的对象,它们应该在哪里?


一般应避免使用全局函数 - 考虑将它们设为静态

类成员如果合适的话。如果你需要一些全局的东西,

把它放在同一个文件中,它与一个类实现很紧密相关,或者单独放在一个文件中。将函数的声明放在

头文件中,该文件包含在适当的位置。这可能是

相同的头文件与一个密切相关的类的声明,或它

本身可能在头文件中,或者它可能在一个文件与其他

全球等等 - 可能性是无穷无尽的。


如果有人能给我一个
解释我会非常感激在这里因为它开始让我迷惑一点
并使我的项目布局有点乱,因为我只是继续移动它们直到编译器没有得到' 某某没有宣布''牛肉。


我希望有所帮助。你可能想得到(或看一下)书籍

写实体代码和/或大规模C ++软件设计,两者都是b / b
对如何将C / C ++
源代码划分为文件的深入讨论和建议。

非常感谢
祝你好了
Hi,
Coming from VB, I''ve still not really grasped the way how
in C++ if function A wants to call function B, then
function B has to be before function A in the
compilation, and #includes that use the classes in others
rely on others have to be after them accordingly.
Important concepts to keep in mind:

Compilation model.

VB (and C# and Java) use a "whole program" compilation model. That is, the
compiler (at least logically if not in fact) looks at the entire program
(assembly, DLL, etc) at once.

C and C++ use a "single module" compilation model. In this model, the
compiler sees a single module at a time, and has no concept or knowledge of
what''s in any other module. By convention, a module is a .C or .CPP file,
but really it''s whatever file is supplied to the compiler on the command
line - there''s nothing special about a ".cpp file" as opposed to a "header
file".

Declarations versus definitions.

Declaration: declares to the compiler that a thing (class, function,
object, etc) exists. Provides all the information necessary to use the
thing (i.e. call a function, reference an object, etc). Analogous to the
"interface" of the thing.

example: a function prototype is a declaration.

Definition: Supplies the details about how the compiler is to build the
thing. A definition which does not match a prior declaration is also
considered a declaration. Analogous to the "implementation" of the thing.

example: a function header with a body is a definition.

In languages like VB, C# and Java, there is no separation of declaration
from definition. Since these languages use a "whole program" compilation
model, the compiler can simply search all of the modules of the program for
the declaration of anything that it needs.

In C and C++, since the compiler only sees one module at a time, it cannot
find the definitions of things that are referenced in one module but defined
in another. You have to help it by providing definitions for everything
that''s referenced, even if it''s not defined in that particular module. By
conveion, the way you supply definitions is through "header files", but
that''s a convention only.
The One Definition Rule

In C and C++ there''s an important rule: The One Definition Rule. Also
referred to as "The ODR". This states that a thing (function, class, etc)
must have a single definition within a complete program or the results are
undefined. Note that''s a single definition, not a single declaration!
There are loopholes for things like inline functions that can, in effect, be
defined several places. The behavior of the program is still undefined if
those defitions are in fact different.
Preprocessing

VB, C#, Java and similar languages have no concept of a preprocessor in the
way that C/C++ does. The preprocessor combines input from one or more files
into a "token stream", which is what the compiler proper consumes. That is,
the compiler itself really doesn''t know anything about files or file names
or naming conventions - it only sees the single linear token stream that the
preprocessor supplies.

Single-pass

C and C++ compilers logically pass through the source code one time, in
order, from top to bottom. In theory, for example, a C++ compiler could
receive it''s token stream through a TCP socket from the preprocessor, which
could, in theory, be running on a separate machine.
Now, with those foundation concepts in mind:


I''ve got three questions about this if I may,

1) When I create an MFC application by having a dialog
class and an application class (generated by the wizard)
as the first four files (CMyDlg.h, CMyDlg.cpp, CMyApp.h
and CMyApp.cpp) and I want to add another class,
CMyClass, which of the four wizard generated files I
mentioned should I #include it in normally? And do I also
have to include the CMyClass.cpp file - or if not, does
it know to pick this file up automatically for the
compilation of the implementation of CMyClass''s functions?
The normal MFC programming convention would be to make two new files:
CMyClass.h and CMyClass.cpp. You''d put the declaration of CMyClass in the
header file and the definition in the .cpp file, then #include CMyClass.h in
the appropriate place(s). If, for example, CMyDlg uses CMyClass in it''s
definition (suppose CMyDlg has a data member of type CMyClass), then you''d
#include CMyClass.h in CMyDlg.h. If the declaration of CMyClass is only
needed by (for example), the definition of CMyApp, then you''d normally
#include CMyClass.h in CMyApp.cpp and not in CMyApp.h. Note that a common
MFC convention is to #include everything in stdafx.h, #include nothing in
other header files, and #include StdAfx.h in all .cpp files. This somewhat
simulates the "whole program" compilation model, since every module contains
a declaration of everything in the program, even if it''s not needed.

2) I experienced strange behavior in VC++.net 2002 when I
wanted to have some #define statements that largely
related to an extra class I added, but would be needed a
bit by my CMainDlg class in its .cpp file aswell, and the
compiler would only accept it if I put them in the added
class''s header file - how did it not work if they were
before all the #includes? What is the general rule for
how you should generally order and place the #include and
define statements if you are building an application that
has two main classes for the dialog and application
objects and lots of others, and you want to keep them in
separate files?
Generally, you should place things (#defines, definitions, declarations,
etc) in a file that''s included in the correct place(s). If the "thing" is a
definition, it needs to be placed in a file that will not violate the ODR.
For example, function defintions and class definitions should be placed in a
"cpp file", unless they''re inline, in which case they should be placed in a
"header file". (Because an inline definition must be visible at every point
that it''s referenced).

3) Where should global functions that some of the classes
might want to call be, and where should they be if those
global functions want to refer to objects that are
instantiated from classes that are defined in different
files?
Global functions should be avoided generally - consider making them static
class members if that''s appropriate. If you need something to be global,
put it in the same file with a class implementation to which it''s closely
related, or in a file by itself. Put the declaration of the function in a
header file that is included in the appropriate place(s). That might be in
the same header file with the declaration of a closely related class, or it
might be in a header file by itself, or it might be in a file with other
globals, etc - the possibilities are endless.


I''d be very thankful if somebody could give me an
explanation here as it''s beginning to confuse me a bit
and making my project layout a bit messy as I just have
to keep moving them around till the compiler hasn''t
got ''so-and-so not declared'' beef.
I hope that helps a bit. You might want to get (or look at) the books
"Writing Solid Code" and/or "Large Scale C++ Software Design", both of which
have in-depth discussions of and recommendations about how to divide C/C++
source code into files.

Many thanks
Best wishes
Ben




-cd



-cd


Ben Taylor写道:
Ben Taylor wrote:
1)当我通过对话创建一个MFC应用程序时......
CMyClass,四个向导生成的文件中的哪一个我
提到我应该#include它正常吗?我是否还必须包含CMyClass.cpp文件 - 如果没有,它是否知道自动选择此文件以编译CMyClass函数的实现?


把#include" MyClass.h"在每个使用CMyClass的源(.cpp)文件中。


重要提示:如果你有一些CMyClass类型的成员变量(因为

反对指向CMyClass的指针) ,或CMyClass *)然后你必须把

#include放在相应的头文件中,而不是源文件。

2)我在VC ++中经历过奇怪的行为.net 2002当我想要一些#define语句与我添加的额外类相关时,但是我的CMainDlg类需要在其.cpp文件中使用它,以及
编译器只会接受它,如果我把它们放在添加的
类的头文件中 - 如果它们在所有#includes之前它是如何工作的呢?如果要构建一个应用程序,对于对话框和应用程序有两个主要类,那么通常如何排序和放置#include和
定义语句的一般规则是什么? >对象和很多其他的,你想把它们保存在单独的文件中?


如果你定义了一个宏(或者你称之为定义语句)

也用在另一个文件中,那么定义必须在它之前'这是

使用。请注意,宏应该在头文件中定义,并且

不在源文件中。


我首先包括Stdafx.h。 (如果我使用它,即如果我使用预编译的

标头),那么在你的情况下,其他系统头文件已经不在
预编译头文件中,然后是主应用程序头文件

MyApp.h,然后源代码的相应标题目前是

编译(源码我把所有这些包括在内),然后是我所有的标题

当前来源需要。这似乎是安全的方式(至少对我来说是b $ b)。

3)某些类可能想要调用的全局函数应该在哪里?如果那些全局函数想要引用从不同
文件中定义的类实例化的对象,它们应该在哪里?
1) When I create an MFC application by having a dialog
...
CMyClass, which of the four wizard generated files I
mentioned should I #include it in normally? And do I also
have to include the CMyClass.cpp file - or if not, does
it know to pick this file up automatically for the
compilation of the implementation of CMyClass''s functions?
Put #include "MyClass.h" in every source (.cpp) file that uses CMyClass.

IMPORTANT: If you have some member variable of type CMyClass (as
opposed to pointer to CMyClass, or CMyClass*) then you have to put
#include in the respective header file, instead of source file.
2) I experienced strange behavior in VC++.net 2002 when I
wanted to have some #define statements that largely
related to an extra class I added, but would be needed a
bit by my CMainDlg class in its .cpp file aswell, and the
compiler would only accept it if I put them in the added
class''s header file - how did it not work if they were
before all the #includes? What is the general rule for
how you should generally order and place the #include and
define statements if you are building an application that
has two main classes for the dialog and application
objects and lots of others, and you want to keep them in
separate files?
If you define some macro (or as you call it a define statement) that
is used in another file too, then the definition must precede it''s
use. Beware that the macro should then be defined in header file, and
not in source file.

I first include "Stdafx.h" (if I use it, i.e. if I use precompiled
headers), then additional system headers that are not already in
precompiled header, then main application header, in your case
"MyApp.h", then the corresponding header for the source currently
compiling (the source I put all these includes), then all my headers
that the current source needs. This seems to be The Safe Way (at least
to me).
3) Where should global functions that some of the classes
might want to call be, and where should they be if those
global functions want to refer to objects that are
instantiated from classes that are defined in different
files?



您拥有所需的所有自由(以及更多)来放置函数,

无论它们是全局的还是属于类。您可以将所有

全局变量放在名为Globals.cpp的文件中,这样您就可以知道在哪里找到它们。如果某些全局函数与某些

类非常密切相关,那么你可以将它放在该类的源文件中,甚至

使它成为该类的静态成员函数。



You have all the freedom you want (and much more) to place functions,
whether they are global or belongs to a class. You could put all the
globals in the file called Globals.cpp just so you would know where to
find them. If some global function is very closely related to some
class then you could put it in the source file of that class, and even
make it static member function of that class.


Ben Taylor写道:
Ben Taylor wrote:
是的,这对Carl很有帮助。
所以它没有''真的很重要,如果.h文件不止一次包含
因此相同的数据不止一次从预处理器发送到
编译器,因为
它只是一个标题文件并不应该占用太多空间
,还是会忽略它之前已经看过的定义?


如果头文件被多次包含,可能会或者可能没有关系,

取决于其中的内容。


通常的做法(再次参见编写固体代码)是使用include

guard。围绕每个头文件的内容


// myfile.h

#ifndef included_myfile_h

#define included_myfile_h


// myfile.h的余额


#endif


守卫的效果是使头文件idempotent -

意味着包含它两次具有与包含它一次相同的效果。


但至于任何东西 - 绝对不是。编译器将检查

预处理标记流中的所有内容并对其进行操作。如果某些东西是重复的,那么它可能是也可能不是错误,这取决于它是什么?b
:记住声明可以重复,而定义则不能。


一些例子:


void f(); //声明 - 可以重复。


void f(){} //定义 - 不能重复(ODR)。


class X; //声明 - 可以重复


class X

{

void xf();

}; //类X的定义 - 不能重复


void X :: f(){} //定义 - 不能重复


inline void g(){] //定义 - 可以重复,因为它是内联的


另外我对静态成员函数不是很清楚。如果我想要一个类具有静态成员函数,我究竟如何定义它以及它与非静态成员之间存在的差异(优点/缺点)
功能?是否可以在没有
引用类的对象的情况下调用它,如果是,
它将如何知道它是否可以使用''this'?



一个静态成员函数实际上(实际上每个编译器都是我所知道的
)只不过是一个普通的;全球"功能有趣的

名称。所以,调用一个静态成员函数不需要这个类的实例,并且

静态成员的体内没有''this''指针可见功能。你使用静态成员函数来控制不需要''this'指针的函数的可见性。


-cd

yes, that helps a lot thanks Carl.
So it doesn''t really matter then if .h files get included
more than once and thus the same data getting sent to the
compiler from the preprocessor more than once, because
it''s only a header file and shouldn''t take up much space
anyway, or will it ignore definitions that it''s already
seen before?
It may or may not matter if a header file gets included more than once,
depending on what''s in it.

Usual practice (again, see "Writing Solid Code") is to use an "include
guard" around the contents of each header file

// myfile.h
#ifndef included_myfile_h
#define included_myfile_h

// balance of myfile.h

#endif

The effect of the guard is to make the header file "idempotent" - which
means that including it twice has the same effect as including it once.

But as for igorning anything - absolutely not. The compiler will examine
everything that''s in the preprocessed token stream and act on it. If
something''s duplicated, it may or may not be an error, depending on what it
is: remember that declarations can be repeated, while definitions cannot.

Some examples:

void f(); // declaration - can be repeated.

void f() { } // definition - cannot be repeated (ODR).

class X; // declaration - can be repeated

class X
{
void xf();
}; // definition of class X - can''t be repeated

void X::f() {} // definition - can''t be repeated

inline void g() {] // definition - can be repeated since it''s inline

Also I''m not that clear on Static member functions. If I
want a class to have a static member function, how exactly
do I define it and what differences
(advantages/disadvantages) does it have over non-static
member functions? Is it that it can be called without
having a reference to an object of the class, and if so,
how will it know if it can use ''this'' or not?

A static member function is, in effect (and in actuality with every compiler
that I know of) nothing more than an ordinary "global" function with a funny
name. So, calling a static member function does not require an instance of
the class, and there is no ''this'' pointer visible within the body of a
static member function. You use static member functions to control the
visibility of functions that don''t need a ''this'' pointer.

-cd


-----原帖-----
Ben Taylor写道:
-----Original Message-----
Ben Taylor wrote:
来自VB,如果函数A想要调用函数B,我还没有真正掌握如何在C ++中使用
函数B必须在函数A之前的
汇编和#includes使用其他人的类
依赖其他人必须相应地追随他们。
Hi,
Coming from VB, I''ve still not really grasped the way how
in C++ if function A wants to call function B, then
function B has to be before function A in the
compilation, and #includes that use the classes in others
rely on others have to be after them accordingly.



要记住的重要概念:

VB(以及C#和Java)使用整个程序。编译模型。那就是,编译器(至少在逻辑上,如果不是实际上)一次查看整个程序(程序集,DLL等)。

C和C ++使用单个模块编译模型。在这个模型中,编译器一次只能看到一个模块,并且没有任何概念或知道任何其他模块中的内容。按照惯例,模块是



Important concepts to keep in mind:

Compilation model.

VB (and C# and Java) use a "whole program" compilation model. That
is, the compiler (at least logically if not in fact) looks at the
entire program (assembly, DLL, etc) at once.

C and C++ use a "single module" compilation model. In this model,
the compiler sees a single module at a time, and has no concept or
knowledge of what''s in any other module. By convention, a module is


.C或.CPP文件,


a .C or .CPP file,

但实际上它是在
命令上提供给编译器的任何文件line - .cpp文件并没有什么特别之处。 as
与头文件相对。

声明与定义。

声明:向编译器声明一个东西(类,函数,
对象等)存在。提供使用该东西所需的所有信息(即调用函数,引用对象等)。
类似于接口。事情。

例子:函数原型是一个声明。

定义:提供有关编译器
but really it''s whatever file is supplied to the compiler on the
command line - there''s nothing special about a ".cpp file" as
opposed to a "header file".

Declarations versus definitions.

Declaration: declares to the compiler that a thing (class, function,
object, etc) exists. Provides all the information necessary to use
the thing (i.e. call a function, reference an object, etc).
Analogous to the "interface" of the thing.

example: a function prototype is a declaration.

Definition: Supplies the details about how the compiler


如何构建的详细信息


is to build the

事情。与先前声明不符的定义也被视为声明。类似于
thing. A definition which does not match a prior declaration is also
considered a declaration. Analogous to


实施事情。


the "implementation" of the thing.


示例:带有正文的函数头是一个定义。

在VB,C#和Java等语言中,没有分离
来自定义的声明。由于这些语言使用整个
程序,编译模型,编译器可以简单地搜索程序的所有模块,以声明它需要的任何东西。

在C和C ++中,由于编译器只看到一个模块在

example: a function header with a body is a definition.

In languages like VB, C# and Java, there is no separation of
declaration from definition. Since these languages use a "whole
program" compilation model, the compiler can simply search all of
the modules of the program for the declaration of anything that it
needs.

In C and C++, since the compiler only sees one module at


一次,它不能


a time, it cannot

找到在一个模块中引用但在另一个模块中定义的事物的定义。您必须通过为所引用的所有内容提供定义来帮助它,即使它没有在特定模块中定义。通过召集,你提供定义的方式是
find the definitions of things that are referenced in one module but
defined in another. You have to help it by providing definitions
for everything that''s referenced, even if it''s not defined in that
particular module. By conveion, the way you supply definitions is


到头文件,但


through "header files", but

这只是一个惯例。

The One定义规则

在C和C ++中,有一个重要的规则:一个定义规则。
也称为ODR。这表明一个东西(函数,类等)必须在一个完整的程序中有一个单独的定义
that''s a convention only.
The One Definition Rule

In C and C++ there''s an important rule: The One Definition Rule.
Also referred to as "The ODR". This states that a thing (function,
class, etc) must have a single definition within a complete program


或结果是


or the results are

undefined。请注意,这是一个单一的定义,而不是一个
声明!像内联函数这样的东西存在漏洞,实际上可以在几个地方定义。如果这些定义实际上是不同的,那么
程序的行为仍然是不确定的。

预处理

VB,C#,Java和类似语言没有概念预处理器就像C / C ++那样。预处理器将输入
undefined. Note that''s a single definition, not a single
declaration! There are loopholes for things like inline functions
that can, in effect, be defined several places. The behavior of the
program is still undefined if those defitions are in fact different.
Preprocessing

VB, C#, Java and similar languages have no concept of a preprocessor
in the way that C/C++ does. The preprocessor combines input


从一个或多个文件


from one or more files

组合成一个令牌流,这是编译器正确消耗的。
即编译器它本身对
文件或文件名或命名约定一无所知 - 它只能看到预处理器提供的单个
线性令牌流。

单通

C和C ++编译器在逻辑上从上到下以
into a "token stream", which is what the compiler proper consumes.
That is, the compiler itself really doesn''t know anything about
files or file names or naming conventions - it only sees the single
linear token stream that the preprocessor supplies.

Single-pass

C and C++ compilers logically pass through the source
顺序通过源


代码。理论上,例如,C ++编译器可以通过来自
预处理器的TCP套接字接收它的令牌流,理论上,它可以在单独的机器上运行。

现在,考虑到这些基础概念:

order, from top to bottom. In theory, for example, a C++ compiler
could receive it''s token stream through a TCP socket from the
preprocessor, which could, in theory, be running on a separate
machine.
Now, with those foundation concepts in mind:


如果可能,我有三个问题,

1)当我创建一个MFC应用程序时,通过一个对话框类和一个应用程序类(由向导生成)
作为前四个文件(CMyDlg.h,CMyDlg .cpp,CMyApp.h
和CMyApp.cpp)我想添加另一个类,CMyClass,我提到的四个向导生成的文件中的哪一个应该正常#include它?我是否还必须包含CMyClass.cpp文件 - 如果没有,它是否知道自动选择此文件以编译CMyClass函数的实现?

I''ve got three questions about this if I may,

1) When I create an MFC application by having a dialog
class and an application class (generated by the wizard)
as the first four files (CMyDlg.h, CMyDlg.cpp, CMyApp.h
and CMyApp.cpp) and I want to add another class,
CMyClass, which of the four wizard generated files I
mentioned should I #include it in normally? And do I also
have to include the CMyClass.cpp file - or if not, does
it know to pick this file up automatically for the
compilation of the implementation of CMyClass''s functions?



正常的MFC编程约定是使



The normal MFC programming convention would be to make


两个新文件:


two new files:

CMyClass.h和CMyClass.cpp。你将CMyClass的声明
CMyClass.h and CMyClass.cpp. You''d put the declaration


放在

头文件和.cpp文件中的定义中,然后#include
CMyClass.h中的适当的地方。例如,如果CMyDlg在其定义中使用CMyClass(假设CMyDlg具有CMyClass类型的数据成员),那么您将在CMyDlg.h中#include CMyClass.h。如果CMyClass的声明只需要(例如),CMyApp的定义,那么你通常会在CMyApp.cpp中#include CMyClass.h而不是CMyApp 。H。请注意,一个常见的MFC约定是#include stdafx.h中的所有内容,#include其他头文件中没有任何内容,以及所有.cpp文件中的#include StdAfx.h。这有点模拟了整个程序。编译模型,因为每个模块都包含程序中所有内容的声明,即使它不需要。
header file and the definition in the .cpp file, then #include
CMyClass.h in the appropriate place(s). If, for example, CMyDlg
uses CMyClass in it''s definition (suppose CMyDlg has a data member
of type CMyClass), then you''d #include CMyClass.h in CMyDlg.h. If
the declaration of CMyClass is only needed by (for example), the
definition of CMyApp, then you''d normally #include CMyClass.h in
CMyApp.cpp and not in CMyApp.h. Note that a common MFC convention is
to #include everything in stdafx.h, #include nothing in other header
files, and #include StdAfx.h in all .cpp files. This somewhat
simulates the "whole program" compilation model, since every module
contains a declaration of everything in the program, even if it''s
not needed.

2)我在VC ++ .net 2002中经历了奇怪的行为,当我想要一些#define语句与我添加的额外类相关时,但是我的CMainDlg类需要一个
位在它的.cpp文件中,如果我把它们放在添加的
类的头文件中,那么
编译器只会接受它 - 如果它们在所有之前它们是如何工作的呢? #includes?如果要构建一个应用程序,对于对话框和应用程序有两个主要类,那么通常如何排序和放置#include和
定义语句的一般规则是什么? >对象和很多其他的,你想把它们保存在单独的文件中吗?

2) I experienced strange behavior in VC++.net 2002 when I
wanted to have some #define statements that largely
related to an extra class I added, but would be needed a
bit by my CMainDlg class in its .cpp file aswell, and the
compiler would only accept it if I put them in the added
class''s header file - how did it not work if they were
before all the #includes? What is the general rule for
how you should generally order and place the #include and
define statements if you are building an application that
has two main classes for the dialog and application
objects and lots of others, and you want to keep them in
separate files?



一般来说,你应该放置东西(#define,



Generally, you should place things (#defines,

定义,声明,


definitions, declarations,

等)在一个包含在正确位置的文件中。
etc) in a file that''s included in the correct place(s).


如果是东西。是一个


If the "thing" is a

定义,它需要放在一个不会违反ODR的文件中。例如,函数定义和类定义应该放在cpp文件中,除非它们是内联的,其中它们应该放在头文件中。 (因为内联
定义必须在它被引用的每一点都可见。
definition, it needs to be placed in a file that will not violate
the ODR. For example, function defintions and class definitions
should be placed in a "cpp file", unless they''re inline, in which
case they should be placed in a "header file". (Because an inline
definition must be visible at every point that it''s referenced).

3)全局函数应该放在哪些类中如果那些全局函数想要引用从不同
文件中定义的类实例化的对象,那么
可能想要调用be,它们应该在哪里?

3) Where should global functions that some of the classes
might want to call be, and where should they be if those
global functions want to refer to objects that are
instantiated from classes that are defined in different
files?



一般应避免使用全局函数 - 如果合适,可以考虑将它们作为静态类成员。如果你需要一些全局的东西,把它放在同一个文件中,它与类实现相关,或者它本身就是一个文件。将函数的
声明放在一个包含在
适当位置



Global functions should be avoided generally - consider making them
static class members if that''s appropriate. If you need something
to be global, put it in the same file with a class implementation to
which it''s closely related, or in a file by itself. Put the
declaration of the function in a header file that is included in the
appropriate place


的头文件中。那可能是在


(s). That might be in

相同的头文件中,声明了一个密切相关的类,或者它本身可能在头文件中,或者它可能在
中文件与其他全局变量等 - 可能性是无穷无尽的。
the same header file with the declaration of a closely related
class, or it might be in a header file by itself, or it might be in
a file with other globals, etc - the possibilities are endless.


如果有人能给我一个
解释我会非常感激在这里因为它开始让我迷惑一点
并使我的项目布局有点乱,因为我只是继续移动它们直到编译器没有得到' '某某某不被宣布''牛肉。


I''d be very thankful if somebody could give me an
explanation here as it''s beginning to confuse me a bit
and making my project layout a bit messy as I just have
to keep moving them around till the compiler hasn''t
got ''so-and-so not declared'' beef.



我希望有所帮助。您可能想要(或查看)
书籍编写固体代码。和/或大规模C ++软件设计,两者都有关于



I hope that helps a bit. You might want to get (or look at) the
books "Writing Solid Code" and/or "Large Scale C++ Software Design",
both of which have in-depth discussions of and recommendations about

的深入讨论和建议如何划分C / C ++


how to divide C/C++

源代码到文件中。
source code into files.

非常感谢
本祝愿

Many thanks
Best wishes
Ben



-cd



-cd
.



这篇关于订购#includes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆