关于 C++ 包含另一个类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12733888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Regarding C++ Include another class
提问by baoky chen
I have two files:
我有两个文件:
File1.cpp
File2.cpp
File1 is my main class which has the main method, File2.cpp has a class call ClassTwo and I want to create an object of ClassTwo in my File1.cpp
File1 是我的主类,它有 main 方法,File2.cpp 有一个类调用 ClassTwo,我想在我的 File1.cpp 中创建一个 ClassTwo 的对象
I compile them together by
我将它们编译在一起
g++ -o myfile File1.cpp File2.cpp
but when I try to create by
但是当我尝试通过创建
//create class two object
//创建类二对象
ClassTwo ctwo;
It doesn't work.
它不起作用。
Error was
错误是
ClassTwo was not declared in this scope.
ClassTwo 未在此范围内声明。
This is my main.cpp
这是我的 main.cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{
//here compile error - undeclare ClassTwo in scope.
ClassTwo ctwo;
//some codes
}
Here is my File2.cpp
这是我的 File2.cpp
#include <iostream>
#include <string>
using namespace std;
class ClassTwo
{
private:
string myType;
public:
void setType(string);
string getType();
};
void ClassTwo::setType(string sType)
{
myType = sType;
}
void ClassTwo::getType(float fVal)
{
return myType;
}
Got respond of splitting my File2.cpp into another .h file but if i am declaring a class, how do i split it into another .h file as i need to maintain the public and private of the variable(private) and functions(public) and how do i get ClassTwo ctwo to my File1.cpp at main method
得到了将我的 File2.cpp 拆分成另一个 .h 文件的回应,但是如果我声明一个类,我如何将它拆分成另一个 .h 文件,因为我需要维护变量(私有)和函数(公共)的公共和私有) 以及如何在 main 方法中将 ClassTwo ctwo 添加到我的 File1.cpp
回答by Alok Save
What is the basic problem in your code?
您的代码中的基本问题是什么?
Your code needs to be separated out in to interfaces(.h) and Implementations(.cpp).
The compiler needs to see the composition of a type when you write something like
您的代码需要分离为接口(.h)和实现(.cpp)。
当您编写类似的东西时,编译器需要查看类型的组成
ClassTwo obj;
This is because the compiler needs to reserve enough memory for object of type ClassTwo
to do so it needs to see the definition of ClassTwo
. The most common way to do this in C++ is to split your code in to header files and source files.
The class definitions go in the header file while the implementation of the class goes in to source files. This way one can easily include header files in to other source files which need to see the definition of class who's object they create.
这是因为编译器需要为类型的对象保留足够的内存,ClassTwo
所以它需要查看ClassTwo
. 在 C++ 中执行此操作的最常见方法是将代码拆分为头文件和源文件。
类定义在头文件中,而类的实现在源文件中。通过这种方式,人们可以轻松地将头文件包含到需要查看它们创建的对象的类的定义的其他源文件中。
Why can't I simply put all code in cpp files and include them in other files?
为什么我不能简单地将所有代码放在 cpp 文件中并将它们包含在其他文件中?
You cannot simple put all the code in source file and then include that source file in other files.C++ standard mandates that you can declare a entity as many times as you need but you can define it only once(One Definition Rule(ODR)). Including the source file would violate the ODR because a copy of the entity is created in every translation unitwhere the file is included.
您不能简单地将所有代码放在源文件中,然后将该源文件包含在其他文件中。 C++ 标准要求您可以根据需要多次声明实体,但只能定义一次(一个定义规则(ODR)) . 包含源文件会违反 ODR,因为在包含该文件的每个翻译单元中都会创建实体的副本。
How to solve this particular problem?
如何解决这个特殊问题?
Your code should be organized as follows:
您的代码应按如下方式组织:
//File1.h
//文件1.h
Define ClassOne
//File2.h
//文件2.h
#include <iostream>
#include <string>
class ClassTwo
{
private:
string myType;
public:
void setType(string);
std::string getType();
};
//File1.cpp
//文件1.cpp
#include"File1.h"
Implementation of ClassOne
//File2.cpp
//文件2.cpp
#include"File2.h"
void ClassTwo::setType(std::string sType)
{
myType = sType;
}
void ClassTwo::getType(float fVal)
{
return myType;
}
//main.cpp
//main.cpp
#include <iostream>
#include <string>
#include "file1.h"
#include "file2.h"
using namespace std;
int main()
{
ClassOne cone;
ClassTwo ctwo;
//some codes
}
Is there any alternative means rather than including header files?
有没有其他方法而不是包含头文件?
If your code only needs to create pointers and not actual objects you might as well use Forward Declarationsbut note that using forward declarations adds some restrictions on how that type can be usedbecause compiler sees that type as an Incomplete type.
如果您的代码只需要创建指针而不是实际对象,您也可以使用前向声明,但请注意,使用前向声明会对该类型的使用方式增加一些限制,因为编译器将该类型视为不完整类型。
回答by S.C. Madsen
C++ (and C for that matter) split the "declaration" and the "implementation" of types, functions and classes. You should "declare" the classes you need in a header-file (.h or .hpp), and put the corresponding implementation in a .cpp-file. Then, when you wish to use (access) a class somewhere, you #include the corresponding headerfile.
C++(和 C 就此而言)将类型、函数和类的“声明”和“实现”分开。您应该在头文件(.h 或 .hpp)中“声明”您需要的类,并将相应的实现放在 .cpp 文件中。然后,当您希望在某处使用(访问)一个类时,您可以 #include 相应的头文件。
Example
例子
ClassOne.hpp:
ClassOne.hpp:
class ClassOne
{
public:
ClassOne(); // note, no function body
int method(); // no body here either
private:
int member;
};
ClassOne.cpp:
ClassOne.cpp:
#include "ClassOne.hpp"
// implementation of constructor
ClassOne::ClassOne()
:member(0)
{}
// implementation of "method"
int ClassOne::method()
{
return member++;
}
main.cpp:
主.cpp:
#include "ClassOne.hpp" // Bring the ClassOne declaration into "view" of the compiler
int main(int argc, char* argv[])
{
ClassOne c1;
c1.method();
return 0;
}
回答by none
you need to forward declare the name of the class if you don't want a header:
如果您不想要标题,则需要转发声明类的名称:
class ClassTwo;
Important:This only works in some cases, see Als's answer for more information..
重要提示:这仅适用于某些情况,有关更多信息,请参阅 Als 的回答。
回答by Peter Wildemann
The thing with compiling two .cppfiles at the same time, it doesnt't mean they "know" about eachother. You will have to create a file, the "tells" your File1.cpp, there actually are functions and classes like ClassTwo. This file is called header-fileand often doesn't include any executablecode. (There are exception, e.g. for inline functions, but forget them at first) They serve a declarative need, just for telling, which functions are available.
同时编译两个.cpp文件的事情,并不意味着他们“了解”彼此。你必须创建一个文件,“告诉”你的File1.cpp,实际上有像ClassTwo这样的函数和类。该文件称为头文件,通常不包含任何可执行代码。(有例外,例如内联函数,但一开始忘记它们)它们服务于声明性需求,只是为了告诉,哪些函数可用。
When you have your File2.cpp
and include it into your File1.cpp
, you see a small problem:
There is the same code twice: One in the File1.cpp
and one in it's origin, File2.cpp
.
当你拥有你的File2.cpp
并将它包含到你的 中时File1.cpp
,你会看到一个小问题:有两次相同的代码:一个在File1.cpp
原点,一个在原点,File2.cpp
.
Therefore you should create a header file, like File1.hpp
or File1.h
(other names are possible, but this is simply standard). It works like the following:
因此,您应该创建一个头文件,例如File1.hpp
or File1.h
(其他名称也是可能的,但这只是标准)。它的工作方式如下:
//File1.cpp
//文件1.cpp
void SomeFunc(char c) //Definition aka Implementation
{
//do some stuff
}
//File1.hpp
//文件1.hpp
void SomeFunc(char c); //Declaration aka Prototype
And for a matter of clean code you might add the following to the top of File1.cpp
:
对于干净的代码,您可以将以下内容添加到 的顶部File1.cpp
:
#include "File1.hpp"
And the following, surrounding File1.hpp
's code:
以及以下,周围File1.hpp
的代码:
#ifndef FILE1.HPP_INCLUDED
#define FILE1.HPP_INCLUDED
//
//All your declarative code
//
#endif
This makes your header-filecleaner, regarding to duplicate code.
这使您的头文件更清晰,关于重复代码。
回答by BigBoss
When you want to convert your code to result( executable, library or whatever ), there is 2 steps:
1) compile
2) link
In first step compiler should now about some things like sizeof objects that used by you, prototype of functions and maybe inheritance. on the other hand linker want to find implementation of functions and global variables in your code.
当您想将代码转换为结果(可执行文件、库或其他)时,有 2 个步骤:
1)编译
2)链接
在第一步中,编译器现在应该了解一些诸如您使用的对象大小、函数原型以及可能遗产。另一方面,链接器希望在您的代码中找到函数和全局变量的实现。
Now when you use ClassTwo
in File1.cpp
compiler know nothing about it and don't know how much memory should allocate for it or for example witch members it have or is it a class and enum or even a typedef of int, so compilation will be failed by the compiler. adding File2.cpp
solve the problem of linker that look for implementation but the compiler is still unhappy, because it know nothing about your type.
现在,当您ClassTwo
在File1.cpp
编译器中使用时,对它一无所知,也不知道应该为其分配多少内存,或者例如它拥有的女巫成员,或者它是一个类和枚举,甚至是 int 的 typedef,因此编译将失败编译器。添加File2.cpp
解决了寻找实现的链接器的问题,但编译器仍然不满意,因为它对您的类型一无所知。
So remember, in compile phase you always work with just one file( and of course files that included by that one file ) and in link phase you need multiple files that contain implementations. and since C/C++ are statically typed and they allow their identifier to work for many purposes( definition, typedef, enum class, ... ) so you should always identify you identifier to the compiler and then use it and as a rule compiler should always know size of your variable!!
所以请记住,在编译阶段你总是只处理一个文件(当然还有那个文件包含的文件),在链接阶段你需要多个包含实现的文件。并且由于 C/C++ 是静态类型的,它们允许它们的标识符用于多种目的(定义、typedef、枚举类,...)始终知道变量的大小!!