【问题标题】:How to access a header member type without scope resolution operator in C++?如何在 C++ 中访问没有范围解析运算符的标头成员类型?
【发布时间】:2018-08-04 07:31:04
【问题描述】:

我正在学习 C++,这可能是一个愚蠢的问题。

我想为通用类型定义创建一个类,并通过 inluding 在许多 cpp 文件中使用它。 标题是“CommonTypesCls.h”:

class CommonTypesCls
{
public:     
    typedef unsigned int UINT32;
    typedef int INT32;
}

我想像这样在 source.cpp 中使用这些属性:

#include "CommonTypesCls.h"
int main()
{    
    int a = sizeof(UINT32);
    return 0;
}

是否可以在没有范围解析的情况下使用包含类的成员类型?

【问题讨论】:

  • 我在您的代码中看不到“属性”。你的意思是“会员类型”吗?
  • 是的,我的意思是会员类型。
  • 固定大小的整数类型由<stdint.h> 提供。 C++ 中的常见约定是为宏符号保留所有大写标识符(尽管许多初学者/新手甚至一些专业人士都会这样做,但您将 Java/Python 约定误用在了一种完全不适合的语言上)。无论如何,请发布真实代码,而不是一些“类似”的伪代码。
  • @Cheersandhth.-Alf:我认为在这种特殊情况下,它看起来更像是对 C 约定的误用,或者可能是 <windows.h> typedefs 的不良影响。
  • 确保你的标题有标题保护。

标签: c++ scope-resolution


【解决方案1】:

类通常是提供通用定义的错误方式:使用namespace。

此外,您似乎想要的固定大小整数类型的特定定义由<stdint.h> 提供。

也就是说,您可以在派生自C 的类的代码中使用来自类C 的public 和protected 定义。但这将使用两个通常错误的工具:提供定义的类和获得访问权限的继承。在某些情况下它仍然是合适的,例如用于提供对 enum 类型中名称的访问。

【讨论】:

    【解决方案2】:

    很久以前,C++ 标准包含 namespace 就是为了这个目的(顺便说一句,你似乎在重新发明一个轮子):

    #include <cstdint>
    
    namespace CommonTypesCls {
      using uint32 = std::uint32_t;
      using  int32 = std::int32_t;
    }
    
    int foo() {
      using namespace CommonTypesCls;
      uint32 a = 666;
    }
    

    如果您的类型特定于特定类,例如依赖于模板参数(例如std::vector&lt;&gt;::value_type),那么您必须在某处使用范围解析运算符,但您可以创建一个别名:

    template<typename Container>
    void bar(Container const&container)
    {
      using value_type = typename Container::value_type;   // scope resolution
      value_type temporary_storage[4];
      for(auto const&x : container) {
        /* do something with x and using temporary_storage */
      }
    }
    

    但是,当使用auto 变量声明时,通常不需要显式指定类型。

    【讨论】:

      【解决方案3】:

      当然:

      #include "CommonTypesCls.h"
      int main()
      {
          typedef typename CommonTypesCls::UINT32 UINT32;
          int a = sizeof(UINT32);
          return 0;
      }
      

      说真的,不是真的。

      【讨论】:

        【解决方案4】:

        不,除非您使用类型别名,否则这是不可能的。

        using UINT32 = CommonTypesCls::UINT32;
        

        但您不应该这样做,因为类不是收集类型定义的合适位置。

        将它们放在全局范围或命名空间中。

        【讨论】:

        • 绝对不在头文件的全局范围内!
        猜你喜欢
        • 2011-06-11
        • 2010-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-30
        • 2015-04-02
        • 2011-05-19
        • 2013-07-19
        相关资源
        最近更新 更多