【问题标题】:Visual Studio allows unrelated class method to access nested private class?Visual Studio 允许不相关的类方法访问嵌套的私有类?
【发布时间】:2015-09-22 21:08:45
【问题描述】:

我正在尝试在 linux 和 windows 上构建我的项目。该项目已经在 Windows 上运行,但我在 GCC 上遇到了一个非常奇怪的错误。考虑以下代码:

Class Base {
 private:
        MessageInfo *createMsg();
}

Class MessageInfo {
private:
       class Message{
         ...
       }
public:
    Message    *messages[MAX_NO_MESSAGES];
...
}

MessageInfo *Base::createMsg(){
...
       MessageInfo *newMsg = new MessageInfo;
       newMsg->messages[i] = new MessageInfo::Message();
...
}

现在的问题是,在 Visual Studio 中,所有东西都可以编译,但在 GCC 中,我收到以下错误:

*错误:MessageInfo::Message 类是私有的

我真的很惊讶代码实际上是在 Visual Studio 中编译而不是在 GCC 中。有什么建议???

编辑:

我想我必须以更好的方式提出我的问题。我的问题是怎么可能在 VS 2005 中编译这样的代码???我在 VS2013 中尝试了我的代码,它给了我与 GCC 相同的错误。所以我并不是说代码是正确的!

【问题讨论】:

  • 我 99% 肯定 GCC 是正确的,而 Visual Studio 是错误的,但我无法引用标准语言来达到这种效果,我也不知道为什么 Visual Studio 会出错 - 这是一个语言的非常非常基本的方面。
  • 你应该发布一个 MCVE。
  • 您能否准确告诉我们您使用的是哪个版本的 Visual Studio?最新版本比旧版本更符合 C++ 标准。
  • 什么版本的 Visual Studio? VS 2015 产生与 GCC 相同的错误:error C2248: 'MessageInfo::Message': cannot access private class declared in class 'MessageInfo'。 VS 2013 也会产生同样的错误。 VS 2012 - 同样的错误。你在用一些过时的东西吗?
  • 这甚至不会远程重现您的问题,因此在您提供可编译示例之前,该问题无法回答。

标签: c++ visual-c++ gcc


【解决方案1】:

在 Visual Studio 2013 中编译:

class MessageInfo {
    class Message { };

public:
    Message *messages[256];    
};

class Base {
    MessageInfo *createMsg();
};

MessageInfo *Base::createMsg() {
    MessageInfo *newMsg = new MessageInfo;
    newMsg->messages[0] = new MessageInfo::Message(); // won't compile
}

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

如您所料,错误是:

error C2248: 'MessageInfo::Message' : cannot access private class declared in class 'MessageInfo'

【讨论】:

  • 我使用的是 Visual Studio 2005,我编译了您所拥有的确切代码。你觉得是编译器版本问题???
  • 是的,我确定就是这样。
【解决方案2】:

编译器是如此不同,我不确定为什么 VS 会允许它编译,我使用的任何编译器都会引发编译错误。 但是,您正在做的事情是思考课程的一种不好的方式。如果你有

class Message {...};

在 MessageInfo 中是私有的,那么您应该无法在课堂之外的任何地方访问它。我们只希望 Message 在 MessageInfo 类中可用,而在其他任何地方都不可用。因此,您不应像在 MessageInfo 中那样返回 Message*,并且您将无法像在 main 中那样访问 Message() 构造函数。不允许以这种方式编程,否则它将完全违背封装的目的。如果您确实希望任何人都可以使用 Message,那么请将其公开,但通常一个类的内部工作对用户来说是隐藏的,这是一个很好的理由:他们不需要担心它。

【讨论】:

    【解决方案3】:

    根据 egrunin 的建议,我使用了他在评论中建议的代码。显然您无法在 Visual Studio 2013 中编译该代码,但我使用 Visual Studio 2005 在我的机器上成功编译了它。这是完整的代码 使用:

     // Test.cpp : Defines the entry point for the console application.
     //
    #include "stdafx.h"
    
    class MessageInfo {
        class Message { };
    
    public:
        Message *messages[256];    
     };
    
    class Base {
        MessageInfo *createMsg();
    };
    
    MessageInfo *Base::createMsg() {
        MessageInfo *newMsg = new MessageInfo;
        newMsg->messages[0] = new MessageInfo::Message(); // won't compile
        return newMsg;
     }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        return 0;
    }
    

    我在这里做错了吗???

    附注:

    我在 Visual Studio 2010 上尝试了代码,我得到了无法访问在类“MessageInfo”中声明的私有类错误!!任何人都可以在 Visual Studio 2005 上编译此代码,以便我知道 VS 2005 出了什么问题????

    【讨论】:

      猜你喜欢
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      • 2018-07-13
      • 2021-07-20
      • 2014-10-06
      相关资源
      最近更新 更多