【问题标题】:c++ Creating a class with a enum produces errorsc ++使用枚举创建类会产生错误
【发布时间】:2015-03-14 12:50:42
【问题描述】:

我正在自学 C++。 我一直在尝试使用枚举变量创建一个类,但它会产生错误。

这是我编码的一部分。

*用于 Main() 的类

#include "Athletics.h"

enum Medal {GOLD, SILVER, BRONZE}; 
enum Event {100_METER_RACE, POLE_VAULT, HAMMER_THROW};

Athletics::Athletics()
{
}

Athletics::Athletics(Medal medal, Event event)
{
    Medal m = medal;
    Event e = event;
}

Athletics::Medal getMedal(){// produces an error, "within this context"
    return Medal; //produces an error, "expected primary-expression before ';' token"
}

*上面类的头部

#ifndef ATHLETICS_H
#define ATHLETICS_H

class Athletics
{
    private:
        enum Medal {GOLD, SILVER, BRONZE}; //produces an error, "'enum Athletics::Medal' is private."
        enum Event {100_METER_RACE, POLE_VAULT, HAMMER_THROW};
    public:
        Athletics();
        Athletics(Medal medal, Event event);
        Medal getMedal();

};
#endif

当我拒绝所有这些枚举和相关的构造函数时,一切似乎都很好。

连同一个 getter (Medal getMedal()),我想为枚举变量创建 setter 方法。

很遗憾,我的教科书显然没有说明为什么会出现这些问题。

如果您能提供任何建议,我将不胜感激。

【问题讨论】:

  • return Medal 应该做什么? Medal 是一种类型。
  • 您的类不包含任何数据成员。它只包含一些成员 type 定义。
  • 感谢您的 cmets。 return Medal 应该返回 Medal 属性的值。我创建它是因为我在 C# 和 Java 方面有一些经验。我想像在 Java 中那样创建它,就像 this.Medal 一样。但是,正如您所提到的,这种方式对于 C++ 来说是错误的。
  • 我的意思是return this.Medal...这可能是我最容易理解的方式。
  • @YMD:即使在 Java 中,您也必须返回枚举的实例。 (在 Java 中,你也可以返回一个类,但我敢肯定这绝对不是你在这里谈论的内容。)

标签: c++ class constructor enums nested


【解决方案1】:
return Medal;

Medalenum 本身的名称。您不能返回枚举类型本身。你必须返回一个特定的枚举object

误解可能从你的类定义开始:

class Athletics
{
    // ...
    enum Medal {GOLD, SILVER, BRONZE};
};

您似乎认为这会创建一个类型和该类型的对象。这是错误的。它只是声明一个类型。你需要给你的班级一个object。如果外部代码应该使用它,您必须将 Medal 公开。

另一个错误:

Athletics::Medal getMedal() {
    // ...
}

这不是成员函数 Athletics::getMedal 的定义,而是一个新的独立函数 getMedal 的定义。

应该是:

 Athletics::Medal Athletics::getMedal() {
     // ...
 }

最后,像100_METER_RACE 这样的标识符应该会导致编译错误。

这是您的代码的固定版本:

// athletics.h:

#ifndef ATHLETICS_H
#define ATHLETICS_H

class Athletics
{
    public:
        enum Medal {GOLD, SILVER, BRONZE}; 
        enum Event {ONE_HUNDRED_METER_RACE, POLE_VAULT, HAMMER_THROW};
        Athletics();
        Athletics(Medal medal, Event event);
        Medal getMedal();
    private:
        Medal medal;
        Event event;
};
#endif

// athletics.cpp:

Athletics::Athletics()    
{
}

Athletics::Athletics(Medal medal, Event event) :
    medal(medal),
    event(event)
{
}

Athletics::Medal Athletics::getMedal() {
    return medal;
}

// main.cpp:

int main()
{
    Athletics athletics(Athletics::GOLD, Athletics::ONE_HUNDRED_METER_RACE);
}

请注意,还有很多事情需要解决。例如,默认构造函数应该如何处理两个成员变量?

另外两个观察结果:


编辑:

您在其中一个 cmets 中提到了 Java,并且您最初发布的此类代码应该可以在那里工作。我不明白你的意思,因为你的 C++ 代码大致相当于 Java 中的以下代码,并且也会产生错误:

class Athletics
{
    private static enum Medal { GOLD, SILVER, BRONZE }

    public Medal getMedal() {
        return this.Medal; // error
    }
}

【讨论】:

  • 谢谢克里斯蒂安、丹尼尔和克雷克。我想我误解了枚举的用法,而不是创建类。
  • 我想再问一个简单的问题。在您的示例代码(反映我对 Java 的理解的底部代码)中,我需要为 Medal 类型声明一个变量,以便 getMedal() 工作。对吗?
  • @YMD:是的。例如:return Medal.GOLD;。这将返回 Medal 类型的对象 - 它返回 the 黄金对象。就像在 C++ 中一样,只是语法略有不同。
  • @YMD:实际上,是也不是。 return Medal.GOLD; 有效,但您没有声明变量。涉及变量声明,它将是:Medal medal = Medal.GOLD; return medal;
  • 非常感谢您扩展了我的知识。我想我学到了很多:)
【解决方案2】:

我不完全确定您的困惑在哪里,因此代码的更正版本可能会有所帮助。首先,您必须意识到枚举是类型,就像intstd::string。定义一个类型并不定义任何对象;您仍然需要定义自己的对象。

struct Athletics
{
    enum Medal { "foo", "bar" };    // defines a type Athletics::Medal

    Medal m_;                       // declares a data member

    Medal getMedal() const { return m_; }

    Athletics(Medal m) : m_(m) {}
};

【讨论】:

    【解决方案3】:

    定义成员函数时,需要告诉编译器它是Athletics的方法:

    Athletics::Medal Athletics::getMedal() { ... }
    

    另外,你不应该在实现文件中声明 另一个 enum,重用来自Athletics 的那个。这也意味着改变构造函数的定义:

    Athletics::Athletics(Athletics::Medal medal, Athletics::Event event)
    

    【讨论】:

    • 关于你的第一句话,其实应该是:“当你定义成员函数时,[...]”
    • @ChristianHackl 已修复。你完全正确,谢谢。
    • 我刚刚在自己的回答中修正了一个类似的错误 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 2015-08-07
    • 2022-08-22
    • 2015-11-08
    • 2020-03-03
    • 1970-01-01
    相关资源
    最近更新 更多