让我具体说明我要做什么,我需要将我的 foo-bar 程序分成五个单独的文件:main、foo.h、foo.cpp、bar.h、bar.cpp。我的头文件(foo.h 和 bar.h)旨在包含其相应类的声明,而 C++ 文件(foo.cpp 和 bar.cpp)旨在定义类。
我使用的是 Visual Studio,到目前为止,唯一显示危险信号的文件是我的主文件。到目前为止,这是我的代码,我将包括在我的主文件中抛出的错误:
主要.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
酒吧.h
#ifndef bar_h
#define bar_h
#include "bar.cpp"
#include "foo.h"
class Bar : public Foo {};
#endif
酒吧.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 func1\n";
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
我的程序在我将其拆分之前一直有效,但现在当我尝试编译它时,它一直向我抛出此消息,并且我的主代码中有几个危险信号。这是控制台告诉我的:
No suitable constructor exists to convert int to Bar
func1 is not a member of class Bar
func2 is not a member of class 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 func1\n";
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;}
现在让我们继续构建我们的项目。如果您使用的是 GCC,那么很容易将其描述为一系列 CLI 命令。由于您使用的是 Visual Studio,因此您必须通过 GUI 执行相应的操作。
首先编译Foo
g++ -c -Wall foo.cpp
下一个编译吧
g++ -c -Wall bar.cpp
编译主体
g++ -c -Wall main.cpp
现在将它们链接在一起
g++ -o main foo.o bar.o main.o
最后运行它,瞧
Inside func1 Data is 25 Inside func2 with 34 Data is 25
关于c++ - 将 C++ 源文件分成多个文件时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47724656/