【问题标题】:Does a private type-specifier prevent objects from 'understanding' the specifier?私有类型说明符是否会阻止对象“理解”说明符?
【发布时间】:2011-10-21 04:16:12
【问题描述】:

我在获取一个接受枚举作为返回类型的函数时遇到了问题。在下面的代码中有一个枚举:

Status{ DEAD, WOUNDED, HEALTHY }

还有一个以 Status 作为返回类型的函数:

Status getStatus();

标题代码:

class Discovery
{
public:
    void doCombat( int );
    void setCombatThreshold( int );
    void setHealth( int );
    void setStatus( int );
    Status getStatus();
private:
    enum Status { DEAD, WOUNDED, HEALTHY };
    Status charStatus;
    int yourHealth;
    int combatThreshold;
};

最初关联的函数定义为:

Status Discovery::getStatus()
{
    switch ( charStatus )
    {
    case DEAD:
        return DEAD;
        break;
    case WOUNDED:
        return WOUNDED;
        break;
    case HEALTHY:
        return HEALTHY;
        break;
    };
}

我找到了这个答案:returning enum from function in C++ base class,它帮助我意识到我确实需要读取函数的第一行:

Discovery::Status Discovery::getStatus()

但是,我的标头代码仍然收到“缺少类型说明符”错误。我意识到在私有访问说明符下使用我的“枚举状态”声明可能会有所不同,因此我将其移至我的标头代码中的公共访问说明符。有效!但我想解释一下为什么它在私有访问说明符下不起作用。我设法在其他地方找到的是:

类的对象不能访问私有数据成员。

我对发生的事情的解释是——使用私有访问说明符下的枚举类型定义,函数(以及最终调用该函数的对象)不可能访问“理解”我的枚举类型,因此接受它作为返回类型。

但是 - 如果是这样的话,为什么我可以返回在私有访问说明符下声明的变量,但存在同样的问题?是不是因为它们的类型已经在别处被理解了,所以程序接受它们没有问题?

【问题讨论】:

  • 其他人已经回答了为什么您遇到编译错误,但这里还有另一个问题。将Status 枚举声明为私有然后将其作为公共函数的返回类型没有任何意义。实例化Discovery 类的任何人都不能调用Discovery::getStatus,因为他们无法访问返回类型。
  • 他们可以调用它,但他们唯一能做的就是将它传递给可以访问状态定义的函数。 (发现或友元函数/类,或派生类)
  • 另外,getStatus 可以简化为Discovery::Status Discovery::getStatus() {return charStatus;}

标签: c++ types enums private access-specifier


【解决方案1】:

状态是在使用后定义的。在 get 方法之前将状态上移。

如果您打算在类之外使用枚举,则需要将枚举移动到公共范围内。

【讨论】:

  • 我通过将私有声明放在公共声明之上来测试它,并且它有效。嗯,这让我脸红。我必须想出一些疯狂的理解,这就是这么简单的事情。感谢您的帮助。
  • @Nico 能够返回私有枚举与枚举是整数这一事实无关。我可以声明一个私有嵌套类并从公共函数中返回它。这是允许的,因为私有对象在类声明中是可见的。但是,除了友元函数,没有人可以调用公共函数并存储返回值。
【解决方案2】:

您需要更改声明的顺序。由于您在声明之前使用 Status,因此它会给您一个错误。您必须将 Status 的声明上移。

class Discovery
{
private:
    enum Status { DEAD, WOUNDED, HEALTHY };
public:
    void doCombat( int );
    void setCombatThreshold( int );
    void setHealth( int );
    void setStatus( int );
    Status getStatus();
private:
    Status charStatus;
    int yourHealth;
    int combatThreshold;
};

【讨论】:

  • 这可能是真的,但不是问题所在。
  • 问题是“为什么第一个失败,为什么第二个成功?”。 OP 假设它与公共/私人定义有关。这是不正确的。问题是因为在公共函数之后声明了状态,这导致了他看到的错误。
  • 应该注意的是,如果 Status 比 getStatus() 更不可见,那么调用者除了将它传递给 Discovery 中的另一个函数之外,不能保存它、比较它或用它做任何事情。 (其中,没有获取 Status 的函数,导致 getStatus() 无法使用。
  • 好吧,它没用,因为它很难使用返回值,但是在不存储返回值的情况下调用它是合法的,或者直接将它传递给一个确实有权限的函数(例如作为朋友功能)。我不确定我是否会这样做,但这是合法的。
  • @Dave,在第二次阅读时,我认为您对 OP 的意图是正确的。抱歉,+1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
  • 2018-01-30
  • 1970-01-01
相关资源
最近更新 更多