繁体   English   中英

当我将C ++类拆分为标头和实现时,出现20个编译器错误,它们没有任何意义

[英]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> 此步骤是可选的,因为在编译单元中多次包含标准头文件没有问题。

其他一些注意事项

  • 在C ++中,尽管不是主要问题,但通常认为使用include <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.hstd::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM