【问题标题】:struct keyword in C++ typedefC++ typedef中的struct关键字
【发布时间】:2014-09-16 16:26:38
【问题描述】:

我在查看 Glew 的标题时遇到了一些问题:

// C
typedef struct __GLsync *GLsync;

我知道 Glew 是一个 C 库,因此与 C++ 不同,我知道这是 C++ 中的有效代码:

// C++
struct S { ... }; // S defined in the class name space
void f( S a ); // struct is optional

我的问题是,从 C++ 中的 typedef 中删除 struct 关键字并在仅限 C++ 的项目中包含标头是否安全?

typedef /*struct*/ __GLsync *GLsync;

如果不是,当我使用 struct 关键字和不使用关键字时,我执行 typedef 会有什么不同?

【问题讨论】:

  • 为什么要删除它?
  • 混合 C 和 C++ 代码的正确方法是使用“extern”。
  • 为了更直接地解决您的问题 - 在 C++ 中,“struct”与“class”非常非常相似。但也有一些区别。如果你想要一个普通的旧 C 结构,“extern”。
  • 前者(带有struct)将编译不管__GLsync是否先前在同一个翻译单元中声明,声明指向某个结构类型的指针的typedef(可能不是那时已知)称为_GLsync。后者(没有struct)需要事先定义实际结构,否则会出现未知类型错误。
  • @3p3r 是的,类似的东西。您可以typedef struct Something *SomeThingPtr; 无需事先在翻译单元遇到Something。编译器会看到它,并简单地推断“我不知道这是什么,但我真的不需要知道来声明一个指针别名。”这与typedef Something *SomethingPtr; 明显不同,后者必须事先了解Something 是什么。当然,当任何代码实际尝试取消引用 SomethingPtr 时,Something 的定义必须已经进入翻译单元。这在粉刺中很常见。

标签: c++ c


【解决方案1】:

以下形式的 typedef:

typedef struct S *SPtr;

不需要事先了解S 在同一翻译单元中的含义。它假定某些结构S 的前向声明和别名SPtr 作为指向相同的指针类型。但是,这个:

typedef S *SPtr; // error unless S is declared earlier 

需要在声明指针别名类型之前已知类型S(可能是结构)的声明。

虽然这看起来微不足道,但它是pimpl idiom 常见实现的基石。请注意,typedef 并没有真正涉及,struct MyClassImpl* 作为指向稍后(但在实际取消引用之前)待确定的未知“事物”的指针类型的声明很重要:

MyClass.h

#ifndef MY_CLASS
#define MY_CLASS

class MyClass
{
   ... members ...

private:
    struct MyClassImpl * m_pimpl; // note no MyClassImpl yet known
};

#endif

MyClass.cpp

#include "MyClass.h"  

// implementation formal declaration and implementation.
struct MyClassImpl
{
    ... members...
};

// MyClass implementation using the now-known MyClassImpl

该指针是否被声明为:

MyClassImpl * m_pimpl;

MyClassImpl 类型需要事先声明,否则会出现编译时错误。

我希望这有助于确定两种声明方法之间的关键区别。 (是的,我知道,我应该使用智能指针 =P)

祝你好运。

【讨论】:

    【解决方案2】:

    这里真正的答案是也许。这取决于在它之前找到了什么其他代码。

    话虽如此,你完全可以改变这一点:

    typedef struct __GLsync *GLsync;
    

    到这里:

    struct __GLsync;
    typedef __GLsync *GLsync;
    

    【讨论】:

    • 嗯,这对我来说看起来更干净。它清楚地表明某些东西正在被前向声明,然后在typedef 中使用,我实际上最终在我的代码中这样做了。谢谢!
    【解决方案3】:

    如果你想从typedef 中删除struct 关键字,那么你必须这样做:

    typedef struct S { ... }__GLsync; // S defined in the class name space
    

    那么你可以使用:

    typedef  __GLsync  *GLsync;
    

    附加问题:

    如果struct 已经被其他人定义了,那么如何解决

     typedef struct __GLsync  *abc;
     typdef  *abc       GLsync
    

    你可以这样做

    【讨论】:

    • 感谢您的回答!但这涉及到我自己定义struct,这有时是不可能的,因为struct是在其他地方定义的,我想做的只是一个简单的typedef
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多