将C 源文件分为多个文件的麻烦
Troubles separating C++ source file into multiple files
让我确切地指定我要做的事情,我需要将我的foo-bar程序拆分为五个单独的文件:main,foo.h,foo.cpp,bar.h.h,bar.cpp。我的标题文件(foo.h and bar.h)旨在包含其相应类的声明,而C 文件(foo.cpp和bar.cpp)旨在定义类。
我正在使用Visual Studio,到目前为止,我显示的危险信号的唯一文件是我的主文件。这是我到目前为止的代码,我将包括在我的主文件中丢弃的错误:
main.cpp
#include <iostream>
#include "foo.h"
#include "foo.cpp"
#include "bar.h"
#include "bar.cpp"
using namespace std;
int main() {
Bar b(25); /*I am getting a red flag under the 25, stating there is no constructor that can convert int to Bar*/
b.func1(); /*I'm getting a red flag under func1 and func2 stating neither of them are members of Bar*/
b.func2(34);
return 0;}
foo.h
#ifndef foo_h
#define foo_h
#include "foo.cpp"
class Foo {};
#endif
foo.cpp
#ifndef foo_c
#define foo_c
#include "foo.h"
#include "bar.cpp"
private:
int data;
public:
Foo(int d) : data(d) {}
int get_data() { return data; }
virtual void func1() = 0;
virtual int func2(int d) = 0;
#endif
bar.h
#ifndef bar_h
#define bar_h
#include "bar.cpp"
#include "foo.h"
class Bar : public Foo {};
#endif
bar.cpp
#ifndef bar_c
#define bar_c
#include "bar.h"
#include "foo.h"
#include "foo.cpp"
Bar(int d) : Foo(d) {}
void func1() {
cout << "Inside func1n";
cout << "tData is " << get_data() << endl;
}
int func2(int d) {
cout << "Inside func2 with " << d << endl;
cout << "tData is " << get_data() << endl;
return d;
}
#endif
我的程序一直在努力,直到我将其拆分为止,但是现在,当我尝试编译它时,它一直向我投掷此消息,并且我的主代码中有几个危险信号。这就是控制台告诉我的:
没有合适的构造函数可以将int转换为bar
func1不是类bar的成员
func2不是类bar的成员
我的问题是:我在做什么错,还有更好的方法可以解决我要做的事情吗?
预先感谢您。
此代码中表现出多个误解。完全纠正它们比单独描述和讨论它们要容易得多。
让我们从依赖树的底部开始。底部是一个虚拟类Foo
。这是其正确的声明。
#ifndef foo_h
#define foo_h
class Foo {
private:
int data;
public:
Foo(int);
int get_data();
virtual void func1() = 0;
virtual int func2(int) = 0;
};
#endif
请注意,我们将其所有方法的声明包括在标题文件中。但是,非虚拟方法的实现已移至foo.cpp
文件中。
#include "foo.h"
Foo::Foo(int d) : data(d) { }
int Foo::get_data() { return data; }
请注意,我们不需要任何特殊设备来保护.cpp
文件的多个包含,因为我们永远不会包含它。
现在Foo
是Bar
类的父母,为我们做一些真正的工作。再次,在类声明中声明了所有方法。
#ifndef bar_h
#define bar_h
#include "foo.h"
class Bar : public Foo {
public:
Bar(int);
void func1();
int func2(int);
};
#endif
及其实现位于称为bar.cpp
的相应汇编单元中。实现类方法时,我们指出该方法属于哪个类,通过将类名称为方法名称,例如Bar::func1
。
#include "bar.h"
#include "foo.h"
#include <iostream>
Bar::Bar(int d) : Foo(d) {};
using namespace std;
void Bar::func1() {
cout << "Inside func1n";
cout << "tData is " << get_data() << endl;
}
int Bar::func2(int d) {
cout << "Inside func2 with " << d << endl;
cout << "tData is " << get_data() << endl;
return d;
}
最后,我们在main.cpp
中使用它,其中只需要一个小更改。
#include <iostream>
#include "foo.h"
#include "bar.h"
using namespace std;
int main() {
Bar b(25);
b.func1();
b.func2(34);
return 0;}
现在让我们继续构建我们的项目。如果您使用的是易于描述为CLI命令序列的GCC。由于您正在使用Visual Studio,因此必须通过GUI执行相应的操作。
第一次编译foo
g++ -c -Wall foo.cpp
下一个编译条
g++ -c -Wall bar.cpp
编译Main
g++ -c -Wall main.cpp
现在将它们全部链接在一起
g++ -o main foo.o bar.o main.o
终于运行它,voila
内部func1 数据是25 在func2内34 数据是25
您切勿#include
.cpp
文件。而是将每个.cpp
文件编译到对象文件中,然后将它们链接到可执行文件中。
在预处理器阶段,编译器将所有#include
D文件拿走,并将它们视为将它们置于一个大型程序中。有时,某些文件可能是多次#include
D。在标题文件中,声明可以重复,但是来自源文件的多个定义会导致错误。(您可能没有这个问题,因为您在源文件中使用了警卫。)
创建对象文件时,编译器将使用标头文件来检查名称和类型,但是不需要实际的定义。发现的定义 汇总到对象文件中。单独的对象文件的目的是将这些定义的汇编分为模块化单元。
- C++击球平均值程序使用输入/输出文件打印名称,平均值,最高/最低平均值时遇到麻烦
- R -RCPP:链接到Shogun C 文件的麻烦
- 在C 中输出到二进制文件中的麻烦
- 在此任务上遇到麻烦,我们需要使用指针和数组来找到文本文件中某些数字的平均值,中值和模式
- C++,映射插入&&文件流读取导致麻烦
- 从C 中的文件阅读麻烦
- 将C 源文件分为多个文件的麻烦
- NeatBeans Makefile:麻烦编译.H文件
- C++处理文件,在制作程序时遇到麻烦
- 麻烦读取.txt文件
- C :将文本文件的内容存储在2D数组中,作为字符串(用于NULL终结器的麻烦?)
- C 麻烦阅读文本文件
- C++从.txt文件中读取+二进制搜索+排序;上课的麻烦
- 在使用头文件/源文件时访问类变量的麻烦
- 在c++中添加第二个.h/cpp文件时遇到麻烦
- 在使用数据结构从文件中读取数据时遇到麻烦
- 在将我写的内容输出到文件时遇到麻烦
- 从文本文件加载时遇到麻烦
- 在c++中读取.csv文件时遇到麻烦
- 麻烦输出矢量到.txt文件