关于C++包括另一个类
Regarding C++ Include another class
我有两个文件:
File1.cpp
File2.cpp
File1 是我的主类,它有 main 方法 File2.cpp 有一个类调用 ClassTwo,我想在我的 File1 中创建 ClassTwo 的对象.cpp
我将它们编译在一起
g++ -o myfile File1.cpp File2.cpp
但是当我尝试通过以下方式创建时
创建类二对象
ClassTwo ctwo;
它不起作用。
错误是
在此范围内未声明 ClassTwo。
这是我的主要.cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{
//here compile error - undeclare ClassTwo in scope.
ClassTwo ctwo;
//some codes
}
这是我的文件2.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;
}
得到将我的 File2.cpp 拆分为另一个 .h 文件的响应,但如果我要声明一个类,我如何将其拆分为另一个 .h 文件,因为我需要维护变量(私有)和函数(公共)的公共和私有,以及如何在 main 方法中将 ClassTwo ctwo 添加到我的 File1.cpp
你的代码中的基本问题是什么?
你的代码需要分离到接口(.h)和实现(.cpp)。
编译器在编写类似
ClassTwo obj;
这是因为编译器需要为类型ClassTwo
的对象保留足够的内存,因此它需要查看ClassTwo
的定义。在C++中执行此操作的最常见方法是将代码拆分为头文件和源文件。类
定义位于头文件中,而类的实现位于源文件中。通过这种方式,可以轻松地将头文件包含在其他源文件中,这些文件需要查看他们创建的类对象的定义。
为什么我不能简单地将所有代码放在 cpp 文件中并将它们包含在其他文件中?
不能简单地将所有代码放在源文件中,然后将该源文件包含在其他文件中。C++标准规定,您可以根据需要多次声明实体,但只能定义一次(一个定义规则 (ODR))。包含源文件将违反 ODR,因为在包含该文件的每个翻译单元中都会创建实体的副本。
如何解决这个特殊问题?
您的代码应按如下方式组织:
//文件1.h
Define ClassOne
//文件2.h
#include <iostream>
#include <string>
class ClassTwo
{
private:
string myType;
public:
void setType(string);
std::string getType();
};
文件1.cpp
#include"File1.h"
Implementation of ClassOne
文件2.cpp
#include"File2.h"
void ClassTwo::setType(std::string sType)
{
myType = sType;
}
void ClassTwo::getType(float fVal)
{
return myType;
}
主.cpp
#include <iostream>
#include <string>
#include "file1.h"
#include "file2.h"
using namespace std;
int main()
{
ClassOne cone;
ClassTwo ctwo;
//some codes
}
除了包含头文件之外,是否有任何其他方法?
如果您的代码只需要创建指针而不是实际对象,则不妨使用前向声明,但请注意,使用前向声明会增加对该类型的使用方式的一些限制,因为编译器将该类型视为不完整类型。
C++(以及C)拆分了类型,函数和类的"声明"和"实现"。您应该在头文件(.h 或 .hpp)中"声明"所需的类,并将相应的实现放在 .cpp 文件中。 然后,当您希望在某处使用(访问)类时,#include 相应的头文件。
例
ClassOne.hpp:
class ClassOne
{
public:
ClassOne(); // note, no function body
int method(); // no body here either
private:
int member;
};
第一类.cpp:
#include "ClassOne.hpp"
// implementation of constructor
ClassOne::ClassOne()
:member(0)
{}
// implementation of "method"
int ClassOne::method()
{
return member++;
}
主.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;
}
同时编译两个.cpp文件并不意味着他们"了解"彼此。 你必须创建一个文件,"告诉"你的File1.cpp,实际上有像ClassTwo这样的函数和类。 此文件称为头文件,通常不包含任何可执行代码。(也有例外,例如内联函数,但一开始忘记它们) 它们服务于声明性需求,只是为了告诉哪些功能可用。
当您拥有File2.cpp
并将其包含在File1.cpp
中时,您会看到一个小问题: 有两次相同的代码:一个在File1.cpp
中,一个在其原点,File2.cpp
。
因此,您应该创建一个头文件,如File1.hpp
或File1.h
(其他名称是可能的,但这只是标准名称)。它的工作原理如下:
文件1.cpp
void SomeFunc(char c) //Definition aka Implementation
{
//do some stuff
}
文件1.hpp
void SomeFunc(char c); //Declaration aka Prototype
对于干净的代码,您可以在File1.cpp
顶部添加以下内容:
#include "File1.hpp"
下面,围绕File1.hpp
的代码:
#ifndef FILE1.HPP_INCLUDED
#define FILE1.HPP_INCLUDED
//
//All your declarative code
//
#endif
这使您的头文件更干净,关于重复的代码。
如果你不想要标题,你需要转发声明类的名称:
class ClassTwo;
重要提示:这仅适用于某些情况,有关更多信息,请参阅 Als 的答案。
当您想将代码转换为 result(可执行文件、库或其他任何内容)时,有 2 个步骤:
1) 编译
2) 链接 在第一步中,编译器现在应该涉及一些事情,例如您使用的对象的大小,函数的原型以及可能的继承。 另一方面,链接
器希望在代码中找到函数和全局变量的实现。
现在,当您在File1.cpp
中使用ClassTwo
编译器对它一无所知,也不知道应该为它分配多少内存,或者例如它拥有的女巫成员,或者它是一个类和枚举,甚至是 int 的 typedef,因此编译器编译将失败。 添加File2.cpp
解决寻找实现但编译器仍然不满意的链接器问题, 因为它对你的类型一无所知。
所以请记住,在编译阶段,您始终只使用一个文件(当然还有该文件包含的文件),而在链接阶段,您需要多个包含实现的文件。 由于 C/C++ 是静态类型的,并且它们允许它们的标识符用于多种目的(定义、typedef、枚举类等),因此您应该始终向编译器标识您的标识符,然后使用它,并且作为规则编译器应始终知道变量的大小!!
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 运行同一解决方案的另一个项目的项目
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- C++从另一个类访问公共静态向量的正确方法是什么
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 使用std::transform将一个范围的元素添加到另一个范围中
- 包括来自另一个文件的运算符重载
- 包括另一个放气到zopflipng
- 在另一个项目中包括继承的类时,抽象类的链接器错误
- 与不包括一个标头更好的使用不完整的标头比另一个标头的使用无效
- 在另一个QMAKE项目中包括一个QMAKE项目
- 关于C++包括另一个类
- 如何有效地使用结构定义,包括来自另一个源文件的运算符
- 包括一个库是否会破坏C++中另一个库的功能
- 将源文件包括在另一个源中
- 得到LNK2005和KNK1169错误-包括一个类在另一个
- 无法在运行时加载动态共享库,包括C++中的另一个共享库
- 如何从一个项目包括一个包含的头文件到另一个?VS2008中
- c++基类未定义.在另一个类中包括基类和子类