【问题标题】:Compiler doesn't like my class C++. getting undeclared identifier error and more编译器不喜欢我的 C++ 类。得到未声明的标识符错误等等
【发布时间】:2016-06-23 05:13:57
【问题描述】:

我创建了一个名为“Message”的类。我想将使用“Message”类创建的消息存储在名为“MessageBox”的类中的静态向量数组中。编译器告诉我 Message 不存在,但编辑器告诉我不存在。以下是带有代码的文件:

“消息.h”

#pragma once
#include <iostream>
#include <string>
#include "Message Box.h"

namespace ATE {
    class Message
    {
    public:
        Message(std::string act, std::string ID, std::string IDtwo) { action = act, ID1 = ID, ID2 = IDtwo; }
        Message(std::string act, std::string ID) { action = act, ID1 = ID; }

        std::string action;
        std::string ID1;
        std::string ID2 = nullptr;

    };

}

“消息框.h”

#pragma once
#include <string>
#include <vector>
#include "Message.h"

namespace ATE {
    class MessageBox
    {
    public:
        static std::vector<Message> MsgBox;
        void addMessage(Message msg);

    };
}

“消息框.cpp”

#include "Message Box.h"

void ATE::MessageBox::addMessage(Message msg)
{
     MsgBox.push_back(msg);
}

我的错误:

错误 C2065 'Message':未声明的标识符(文件:message box.h,行:11)

错误 C2923 'std::vector': 'Message' 不是参数 '_Ty' 的有效模板类型参数(文件:message box.h,行:11)

错误 C2061 语法错误:标识符“消息”(文件:message box.h,行:12)

非常感谢您的帮助(:

【问题讨论】:

  • "Message.h" #pragma once // 你是否忘记了 pragma once? #include // #include "Message Box.h" // 为什么要在 message.h 文件中包含消息框? ... /// std::string ID2 = nullptr; // 你是什么意思?
  • 是的,我有一次编译指示,但我忘了把它复制到这个问题中。 “Message.h”中的#include“Message Box.h”来自我的一个旧消息系统想法,但后来我开始切换东西。 std::string ID2 = nullptr 是因为它可能永远不会有值。我在“Message.h”中取出 Message Box.h”,现在出现链接错误
  • 对这里发生的事情进行更深入的讨论:Resolve header include circular dependencies in C++
  • 是的,我讨厌重构代码,因为我总是在这里和那里留下一点点。下面答案的第二部分让我摆脱了链接错误。谢谢大家的帮助
  • 您正在使用 Visual Studio 进行编译,因此请注意 windows.h 有 #defining MessageBox 的讨厌习惯。您可能会突然在 ATE::MessageBoxW 上看到一个错误,宏不尊重范围。

标签: c++ arrays class vector


【解决方案1】:

您的标题相互包含。由于#pragma once,如果您首先在某些.cpp 文件中包含Message.h,编译器将在Message.h“内部”看到Message Box.h 的内容——恰好在#include "Message Box.h" 行。结果,编译器将按以下顺序处理您的源代码:

source.cpp:
  //#include "Message.h"
message.h:
  //#pragma once
  //#include <iostream>
iostream:
  //iostream's content
message.h(resumed):
  //#include <string>
string:
  //string's content
message.h(resumed):
  #include "Message Box.h"
Message Box.h:
  #pragma once
  #include <string>
  // string's content already included, won't include again
  #include <vector>
  // vector's content
  #include "Message.h"
  // message.h won't include again, due to the #pragma once

  namespace ATE {
      class MessageBox
      {
      public:
          static std::vector<Message> MsgBox;

此时使用名称Message,但编译器尚未达到它在Message.h 中的定义并给您一个错误。

删除#pragma once 无济于事。您需要删除循环依赖。在这种情况下,从 Message.h 中删除 #include "Message Box.h" 就可以了。

【讨论】:

  • 感谢您的完整解释,我很感激。我在重构代码时不小心留下了那个标题并且没有注意到
【解决方案2】:
  1. 在“Message.h”中,删除:

    #include "Message Box.h"

它在Message 之前添加Message Box 声明。

  1. 在“Message Box.cpp”的includes后面添加这一行:

    std::vector&lt;ATE::Message&gt; ATE::MessageBox::MsgBox;

static 成员必须在外部再次声明。

【讨论】:

  • 谢谢,这行得通(:正如你所知,我对 C++ 有点生疏了。几个月没用它编程了
猜你喜欢
  • 1970-01-01
  • 2014-08-17
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
  • 2022-03-09
  • 1970-01-01
相关资源
最近更新 更多