C 和 C++ 类型之间的区别 (typedef)

Difference between in C and C++ types (typedef)

我试图通过重新设计 API 我在学期期间从 DB class 完成的项目(创建自己的数据库系统)来理解 C 和 C++ 之间的区别用C语言写的。现在我正在尝试重新设计 API 项目,它也可以用于用 C++ 语言编写的应用程序。

我对 typedef structenumfloat 等感到困惑

我的头文件 C 代码如下所示:

typedef enum { FALSE = 0, TRUE } bool_t;
typedef float  real;
...
typedef  struct _hf_record_identification {
    int pagenum;
    int recnum;
} RECID;

在阅读了一些有关它的参考资料后,我得出结论,它可以用 C++ 表示为:

enum bool_t {FALSE = 0, TRUE };
float real;
...
struct _hf_record_identification RECID {
    int pagenum;
    int recnum;
} ;

我的问题是:typedef in C 和 typedef 之间的主要区别是什么 C++?在 C++ 中使用 typedef 对我来说并不方便。我把它和 C 搞混了。我在 typedef float real 案例中做对了吗?

这种方法已经过时了。要编写与 C++ 兼容的 C 代码,您将使用两种语言的原生 bool 类型(1999 年在 C 中引入),而不是一些 1990 年代的宏。

#include <stdbool.h> 然后使用 booltruefalse

即使不需要 C++ 兼容性,在 C 中使用你自己的、自制的 bool 类型总是不好的做法。

这一行:

typedef float real;

实际上只是一个 typedef,它将 real 定义为类型 float 的别名。所以如果你写

float real;

不同,无论是在 C 中还是在 C++ 中。它只是一个类型为 float.

的变量 real 的声明

使用 structenum,事情变得有点复杂,因为它们有所谓的 标签 来识别它们:

struct foo
{
    int x;
};

此处:foo 是结构的标签。在 C++ 中,您可以通过只写标记来引用结构(只要标记名称没有歧义),而 C 要求您始终包含 struct 关键字:

struct foo a; // legal in both C and C++
foo b;        // legal only in C++

当然,你也可以使用typedef创建别名类型,以上面的例子为例:

typedef struct foo foo;

现在,第二个声明也是有效的 C,因为 foo 是一个类型名称。

相同的规则以相同的方式适用于 enums。

请注意,C++ 不是自动 typedefstructenum。它只允许单独使用标签名称来引用这些类型。因此,额外的 typedef 是绝对有效的 C++。

因此,如果您的代码应该同时使用 C 和 C++(您通常只对头文件有这种要求),只需像这样声明您的 struct

typedef struct foo foo;
struct foo
{
    // members
};

或压缩成一个声明:

typedef struct foo
{
    // members
} foo;

请注意,C++ 还有一个缺陷。考虑以下代码:

struct foo
{
    int x;
};

typedef struct foo *foo;

(旁注:typedef使用指针是个坏习惯,这里仅用于简单演示)

此代码是有效的 C,但不是有效的 C++。原因是 C++ 需要与结构或枚举标记同名的 typedef 来引用完全相同的结构或枚举类型。在C中,没有这样的要求。

在 re-creating C 接口中没有太多(更准确地说:没有任何)使用,只是将 typedef enum {} X 替换为 enum X {} 等,因为 C 代码被很好地接受了也由 C++ 编写——除非您面临任何与 C++ 不兼容的视图 C-features(例如 header 的内联函数中使用的 VLA)。否则,您只是在复制代码,这将导致可维护性问题,而没有任何进一步的利润。

当然,C++ 包装器 可以 有用,但是您需要为现有的 C 接口创建类似 C++ 的接口,引入 object 方向和可能的多态性,例如如下所示:

// FILE wrapper in C++:
class File
{
    FILE* handle;
public:
    int read();
    int write();
    // or whatever you consider appropriate
};

// sockets:
class Socket
{
public:
    // some appropriate common interface
};
class SocketTCP : public Socket
{
    // appropriate specialization...
};
class SocketUDP : public Socket
{
    // appropriate specialization...
};

很有可能,您可能会用这样的 类 替换 C 结构,然后环绕 C 类型,但是枚举,您可能会保持原样 - 除非您希望它们具有不同的范围(例如,将其中一些嵌套在 类 或命名空间中)。