C ++中奇怪的外部类函数定义? [英] Weird outside class function definition in C++?

查看:90
本文介绍了C ++中奇怪的外部类函数定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好。

我是C ++的文盲,所以我觉得很奇怪。一个例子就是这个。

Hi guys.
I''m C++ illiterate, so i find things weird. One example is this.

展开 | 选择 | Wrap | 行号

推荐答案

这是我的事还有点困惑,但我会尝试解释:


在.h文件(头文件)中,你声明你的在主程序中,当你导入这个.h文件时,你告诉程序,嘿,有一个名为THIS的类,它具有所有这些函数和属性。 ;这样,主.cpp文件可以相信它们已经被正确实现并实例化了这个对象等。此时,所有主要程序都关心的是这个存在 - 而不是它是如何实现的。


现在,当您开始使用THIS对象时,主程序需要查找实现。实际代码包含在另一个.cpp文件中,因此主程序在那里查找正确的函数,执行该代码,并且很高兴。代码和定义是分开的(我认为!),这样,如果你的主程序只使用你的THIS类中的3个函数中的3个,它不必加载和解释其他97个函数,因为它们在你的。 h文件。


我也知道,如果您在类中使用模板,则必须在同一文件中定义依赖于该模板的函数
This is something that I''m still a little confused about, too, but I''l try and explain:

In the .h file (header file), you are declaring your class, along with functions, member variables, etc. In your main program, when you import this .h file, you are telling the program, "Hey, there exists a class called THIS which has all of THESE functions and properties." That way, the main .cpp file can trust that they have been implemented correctly and instantiate THIS objects, etc. At this point, all the main program cares about is that THIS exists - not how it''s implemented.

Now, when you start using THIS objects, the main program needs to look for the implementation. The actual code is included in another .cpp file, so the main program looks in there for the correct function, executes that code, and is happy. The code and definition is seperated (I think!) so that, if your main program only uses 3 out of 100 functions in your THIS class, it doesn''t have to load and interpret the other 97 functions because they were in your .h file.

I also know that, if you ever use templates in your classes, the functions depending on that template must be defined in the same file.



这也是我仍然有点困惑的事情,但我会尝试解释:


在.h文件(头文件)中,您声明您的类,以及函数,成员变量等。在主程序中,导入时这个.h文件,你告诉程序,嘿,有一个名为THIS的类,它具有所有这些功能和属性。这样,主.cpp文件可以相信它们已经被正确实现并实例化了这个对象等。此时,所有主要程序都关心的是这个存在 - 而不是它是如何实现的。


现在,当您开始使用THIS对象时,主程序需要查找实现。实际代码包含在另一个.cpp文件中,因此主程序在那里查找正确的函数,执行该代码,并且很高兴。代码和定义是分开的(我认为!),这样,如果你的主程序只使用你的THIS类中的100个函数中的3个,它不必加载和解释其他97个函数,因为它们在你的。 h文件。


我也知道,如果您在类中使用模板,则必须在同一文件中定义依赖于该模板的函数
This is something that I''m still a little confused about, too, but I''l try and explain:

In the .h file (header file), you are declaring your class, along with functions, member variables, etc. In your main program, when you import this .h file, you are telling the program, "Hey, there exists a class called THIS which has all of THESE functions and properties." That way, the main .cpp file can trust that they have been implemented correctly and instantiate THIS objects, etc. At this point, all the main program cares about is that THIS exists - not how it''s implemented.

Now, when you start using THIS objects, the main program needs to look for the implementation. The actual code is included in another .cpp file, so the main program looks in there for the correct function, executes that code, and is happy. The code and definition is separated (I think!) so that, if your main program only uses 3 out of 100 functions in your THIS class, it doesn''t have to load and interpret the other 97 functions because they were in your .h file.

I also know that, if you ever use templates in your classes, the functions depending on that template must be defined in the same file.



Ganon几乎是正确的。 ;)


C ++继承C'的在使用前声明成语。这意味着您必须在使用之前声明所使用的签名。头文件由要使用的函数/变量/类/结构/枚举的原型(也称为声明)组成。源文件由哪些定义/主体组成(大多数情况下,我会马上进入)。


如果你有头文件中的函数'或变量'的定义,这将导致每次将头文件包含到源文件中时,为一个声明的主体生成多个代码/数据实例。这反过来会导致链接错误,表明您对该函数/变量有多个定义。对于初学者来说,这可能会令人困惑,因为错误似乎指向同一行,但由于它是从差异源文件中包含的,因此它实际上是一个不同的实例。


类/结构和枚举略有不同,因为实际上没有生成代码或数据,因此不会发生链接问题。但是,您可以在头文件中声明类/结构或枚举,而无需实际定义它。这可以通过声明使用来完成。因为编译器所有枚举/引用或指针类型都有相同的底层物理表示,但不是相同的逻辑表示。


听起来很奇怪?嗯,没有你想象的那么多。考虑一下:您希望通过指针或引用传递类/结构或枚举,但不希望任何人知道底层实现是什么或其接口/值。你怎么能这样做?通过声明类/结构或枚举而不定义它。为了使用class / struct或enum,你必须将它传递给一个知道如何操作它的函数。


但是,你可能知道,类/结构和枚举能够在头文件中定义。这允许类/结构或枚举的用户在其代码中以更具交互性的方式使用。


现在在我的第二段中,我使用标题将声明与定义分开,源文件。这并非总是如此。如果在头文件中定义函数为static(不在类/结构构造中),则告诉编译器生成包含它的源文件的本地代码。这意味着将存在与头文件包含的函数体一样多的实例。如果包含100次,则会有100个实例。这可能是很多代码膨胀,但在某些情况下很有用。


此外,在当前的C ++实现中,模板定义必须对使用它们的代码可见。这不是标准所要求的,而是一种解决方法,因为对象/库文件中没有模板的当前二进制表示(对象/库文件应该是与语言无关的)。在代码被其他一些具体函数调用(调用)之前,实际上不会生成代码实例。如果模板函数调用另一个模板函数,则在由具体函数调用之前,不会生成由该模板函数调用链生成的代码实例。

现在出于以下原因:


编译源文件时,会生成二进制对象文件。该对象包含从源生成的所有代码。通过将声明与定义分开,编译器不必一遍又一遍地重新编译相同的代码。它只知道周围有函数/变量具有特定的签名和名称,并假设在链接期间,这些将是可用的。如果他们不是,你会得到一个链接错误,说没有找到这样的定义。


我所说的大多是真的,我有几件事情已经遗漏了,可能有一些错误,因为我在写这个以外的生活;)。这是一本书的良好开端:)。如果我让你感到困惑,请回信,我会尽力让它更清楚。 :D


Adrian

Ganon is sorta mostly right. ;)

C++ inherited C''s "declare before use" idiom. This means that you must declare the signature of what you are using prior to using it. The header file is to consist of the prototypes (aka declarations) of the functions/variables/classes/structs/enums that are to be used. Where as the source file is to consist of the definitions/bodies of the same (well mostly, I''ll get in to that in a moment).

If you were to have a function''s or variable''s definition in the header file, this will result in there being multiple code/data instances generated for the body of one declaration every time you include the header file into a source file. That in turn will result in a linking error stating that you have multiple definitions for that function/variable. To the uninitiated, this could be confusing as the error appears to be pointing at the same line, but since it is being included from a difference source file, it is actually a difference instance.

Classes/structs and enums are slightly different because no code or data is actually generated so no linking problems will occur. However, you can either declare the class/struct or enum in the header file without actually defining it. This can done with "declare be for use" because to the compiler all enums/reference or pointer types have the same respective underlying physical representation, though not the same logical one.

Sounds weird? Well, not as much as you think. Consider: you want a class/struct or enum to be passed around by pointer or reference but don''t want anybody to know what the underlying implementation is or its interface/values. How can you do that? By declaring the class/struct or enum without defining it. In order to use the class/struct or enum, you would have to pass it to a function that does know how to operate on it.

However, as you probably know, classes/structs and enums are capable of being defined in the header file. This allows the user of the class/struct or enum to use in a more interactive way in their code.

Now in my second paragraph, I separated the declarations from the definitions using header and source files. This is not always the case. If you define a function as static in you header file (not within a class/struct construct), you are telling the compiler to generate code local to the source file that is including it. This means that there will be as many instances of that function body as are includes to the header file. If this is included 100 times, you will have 100 instances. That could be a lot of code bloat, but is useful under certain circumstances.

Additionally, under the current implementations of C++, templates definitions must be visible to the code that uses them. This is not required by the standard, but is a workaround as there are no current binary representations of templates in object/library files (object/library files are supposed to be language independent). Code instances are actually not generated until the code is invoked (called) by some other concrete function. If a template function calls another template function, the code instance resulting from that template function call chain is not generated until it is called by a concrete function.

And now for the reason:

When you compile a source file, you generate a binary object file. This object consists of all the code generated from the source. By separating the declaration from the definition, the compiler doesn''t have to recompile the same code over and over again. It just knows that there are functions/variables around that have a particular signature and name and will assume that during linking, these will be available. If they are not, you will get a linking error saying that the definition is not found for such and such.

What I have said is mostly true, there are a few things that I have left out and there are probably a couple of errors due to me having a life outside of writing this ;). This is a good start of a book :). If I have confused you, please write back and I will endeavour to make it clearer then mud. :D


Adrian


你们当然知道你的东西。

我得到了一些什么你说阿德里安。但是,对于同一代码的多次复制的解决方案是不是在头文件中使用#ifndef?如果未定义类,请使用其所有方法定义对其进行定义。这不会阻止编译器多次粘贴相同的代码吗?
You guys certainly know your stuff.
I got some of what you said Adrian. But wouldn''t the solution to the multiple copying of the same code be using a #ifndef in the header file? If the class is not defined, define it with all it''s method definitions. Won''t this stop the compiler to paste the same code multiple times?


这篇关于C ++中奇怪的外部类函数定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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