收到语法和意外令牌错误,有人知道原因吗?

时间:2019-02-13 02:11:38

标签: c++ visual-studio-2017

我有一个拒绝合作的头类,我已经解决了许多错误,但是我一生都无法获得这两个错误。有什么想法吗?

#pragma once
#include <iostream>
#include <string>
#include <conio.h>

using namespace std;
#ifndef EndageredSpecies
#define EndageredSpecies
using namespace std;
class EndageredSpecies
{
public:
    EndageredSpecies;
    EndageredSpecies(string newName, newLevel, newReason);
    void setName(string newName);
    void setLevel(string newLevel);
    void setReason(string newReason);
    string getName();
    string getLevel();
    string getReason();
    void print();
private:
    std::string name;
    std::string level;
    std::string reason;
};

void do_something()
{
    cout << "Doing something";
}
#endif

错误是:

C2059语法错误:')'-第13行

C2238在';'-第13行之前的防晒令牌

(第13行是'EndageredSpecies(string newName,newLevel,newReason);')

1 个答案:

答案 0 :(得分:1)

您的代码对编译器来说是什么样子(请注意,我没有处理include语句,因为虽然更准确,但会造成很多麻烦):

#pragma once
#include <iostream>
#include <string>
#include <conio.h>

using namespace std;
using namespace std;
class 
{
public:
    ;
    (string newName, newLevel, newReason);
    void setName(string newName);
    void setLevel(string newLevel);
    void setReason(string newReason);
    string getName();
    string getLevel();
    string getReason();
    void print();
private:
    std::string name;
    std::string level;
    std::string reason;
};

void do_something()
{
    cout << "Doing something";
}

这是为什么?

#define EndageredSpecies

告诉预处理器将EndageredSpecies替换为#define EndageredSpecies之后的任何行,在这种情况下绝对没有,所以

class EndageredSpecies

现在是

class 

等...

您必须非常小心使用#define宏。它们执行起来非常简单。他们没有大脑。如果他们看到被告知要替换的令牌,则将其替换。期。我曾经犯过一个错误,即定义int strlen;来包含字符串的长度。

大错误。

原来strlen函数是作为宏实现的。 int strlen;成为int <whole function body here>;。我想我花了大部分时间来解决这个问题。

不要害怕宏,但是您必须非常小心地使用它。

您真正想要的是

#pragma once
#ifndef UNIQUE_AND_NEVER_REPEATED_IDENTIFIER
#define UNIQUE_AND_NEVER_REPEATED_IDENTIFIER
// note how this is above the includes. Don't want to re-include them

#include <iostream>
#include <string>
#include <conio.h>

// do not use using namespace std; in a header. It's a very nasty surprise 
// to other programmers.
class EndageredSpecies
{
public:
    EndageredSpecies(); // added brackets
    EndageredSpecies(std::string newName, // added std namespace 
                     std::string newLevel, 
                     std::string newReason);
    void setName(std::string newName);
    void setLevel(std::string newLevel);
    void setReason(std::string newReason);
    std::string getName();
    std::string getLevel();
    std::string getReason();
    void print();
private:
    std::string name;
    std::string level;
    std::string reason;
};

void do_something()
{
    std::cout << "Doing something";
}
#endif

旁白:

#pragma once

#ifndef EndageredSpecies
#define EndageredSpecies
#endif

是制作include guard的两种方法。您可以同时使用两者,但是通常不需要。

#pragma once

不是Standard C ++的一部分,因此您不能指望它被支持。允许编译器不支持的任何pragma静默丢弃,从而导致混乱,灾难,甚至可能没有有用的错误消息。也就是说,如今大多数编译器都实现onceonce可能由于it has severe failure cases in complicated build environments尚未标准化。别偷偷摸摸,一切都很好。

#ifndef EndageredSpecies
#define EndageredSpecies
#endif

随时随地工作。问题就像问问者所经历的那样。

请勿重复包含保护标识。曾经出于任何原因。

名字包括警卫,以便除非您发疯,否则他们几乎不可能重复。可悲的是,诺曼·贝茨(Norman Bates)钉住了它:有时候我们都会发疯。为了防止暂时的疯狂,请使其尽可能明显,以便以后不再生气时,可以看到所使用的标识符在何处使用是没有意义的,然后进行更改。

通常,您只需要其中一种或另一种包含保护,但是同时使用它们可能会有好处。如果#pragma once不被支持或失败,您将不会感到讨厌。如果支持,则完全不必查看包含的文件通常会带来性能上的好处。