[英]When I split up my C++ class into a header and implementation I get 20 compiler errors which don't make sense
我通常将程序分为头文件和实现文件,但是,当我尝试运行代码时,遇到了大量编译错误。 这似乎是我的计算机或IDE的问题,但我之前从未见过。 就班级项目而言,这应该相对简单。 代码如下:
colorPicker.h
#pragma once
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
colorPicker.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
colorPicker::colorPicker() {
colorArray[0] = "Red";
colorArray[1] = "Green";
colorArray[2] = "Purple";
colorArray[3] = "Yellow";
colorArray[4] = "Orange";
colorArray[5] = "Indigo";
colorArray[6] = "Pink";
}
void colorPicker::printAllColors() {
for (int i = 0; i < 7; i++) {
cout << colorArray[i] << endl;
}
}
string colorPicker::randomColor() {
srand((unsigned)time(0));
int j = 0;
j = rand() % 7;
return colorArray[j];
}
main.cpp中
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
colorPicker p;
p.printAllColors();
cout << "Random Color: " << p.randomColor() << endl;
system("pause");
return 0;
}
编译器给出了20个错误,但是它们似乎都来自于两个未声明的标识符,这些标识符是最明确声明的。 我不知所措,无法修复它,这个项目应在周日进行。 谢谢。
这是错误大量的错误
您需要在colorPicker.cpp
#include "colorPicker.h"
。 每个.cpp文件基本上由编译器独立处理,并且最后都由“链接器”连接在一起。 当编译器在不包含相应头的情况下查看colorPicker.cpp
,您正在使用的所有类的定义都将丢失。
您做错了几件事。 我只选一对。
首先,您编写的每个头文件都应该是独立的-从某种意义上来说,如果它依赖于其他头文件的内容,则它包含该头文件。 如果编译单元(在您的情况下为.cpp的源文件的正式名称)包含您的标头,则它不必包含标头所依赖的其他内容。
其次,对于标头依赖任何using指令(例如using namespace std
,都是一个坏主意。 有很多可用的解释,所以我不再重复。
要了解以上内容,请查看colorPicker.h
class colorPicker { private: string colorArray[7]; public: colorPicker(); void printAllColors(); string randomColor(); };
首先,这取决于string
,但是在头文件中没有可见的string
定义。 该类型的用法取决于标准头文件<string>
。
其次,该string
类型在命名空间std
。 因此,您的标头依赖于以前使用过using指令(即using namespace std
)的编译单元(包括标头的源文件)。
要解决这两个问题,请将标题更改为
#ifndef SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#define SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#include <string>
class colorPicker
{
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
(我还做了一些小的布局更改,因为出于各种原因我更喜欢这么做。
但是, #include <string>
意味着,如果该版本被没有#include <string>
的编译单元所包含,则该版本将不会像您一样失败。
使用标准名称std::string
而不是string
,也意味着不依赖于using namespace std
的using指令。 这也意味着如果您的编译单元具有另一个using指令,则无法在标头中触发编译错误。
我还使用了include卫兵,而不是#pragma once
。 尽管大多数现代编译器#pragma once
支持#pragma once
,但实际上它不是标准的C ++(按照标准的定义, #pragma
是编译器特定的钩子)。 标准C ++支持包含保护。
如果您这样做了,那么您的代码应该基本上可以按原样编译。 但是,可选地,您可能希望
using namespace std
的using指令。 如果这样做,则需要在colorPicker::randomColor()
更改colorPicker::randomColor()
的定义,以便它返回标准类型std::string
而不是string
。 #include "colorPicker.h"
文件中删除#include <string>
。 这是可能的,因为colorPicker.h现在包括<string>
。 此步骤是可选的,因为在编译单元中多次包含标准头文件没有问题。 其他一些注意事项
<cstdio>
和<cstdlib>
比使用C头文件<stdio.h>
和<stdlib.h>
更好。 colorPicker::randomColor()
时,您的代码就会调用srand((unsigned)time(0))
。 最好只在整个程序中调用一次,而不是在可能多次调用的函数中调用。 您可能需要在colorPicker.h中添加头文件。 使用字符串时需要std名称空间。
顺便说一句,强烈建议使用头部保护装置。
#ifndef COLOR_PICKER_H
#define COLOR_PICKER_H
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
头文件应该是自包含的,直到#include
为止。 这意味着您应该能够#include
头文件, 而不必在其之前包含其他内容!
您的colorPicker.h
不满足该要求。 它显然使用了标准库中的std::string
,但顶部没有#include <string>
,因此使用colorPicker.h
每个人都必须记住在其前面加上#include <string>
。 真烦人。
更糟糕的是, colorPicker.h
将std::string
称为string
,这意味着using std::string;
或using namespace std;
任何#include "colorPicker.h"
行之前的某处,如果未在更严格的范围内使用,则这两种都是C ++中非常糟糕的编码样式。
这是修复头文件的方法:
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
至于您的* .cpp文件,我可以看到您正在使用#include "stdafx.h"
。 为什么? 对于您而言,这是非标准的Microsoft事情,完全没有必要。 您也使用不正确。 它必须是第一个包含。 只需将其完全删除即可。
建议进行其他一些清理:
using namespace std;
* .cpp文件中的行并不比头文件中的行糟,但是如果我是你,我会完全摆脱它。 只需使用完整名称即可。 说std::cout
,而不是cout
。 等等。 这只是最一致的方法,它避免了很多麻烦。 <ctime>
是做什么的? system("pause");
。 不要寻找人为的方式来暂停命令行程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.