【问题标题】:How to transform C++ code into C in an elegant way [duplicate]如何以优雅的方式将 C++ 代码转换为 C [重复]
【发布时间】:2012-09-23 05:20:03
【问题描述】:

可能重复:
Code convert from C++ to C
Converting a C++ class to a C struct (and beyond)

我曾经是一名 C++ 程序员,但现在我需要用 C 编写程序。 例如在 C++ 中

Main.cpp
=====================
int main
{
  ns::Sum sum(1, 2);
}

Sum.h
=====================
namespace ns
{
  class Sum
  {
    public:
    Sum(int a, int b);
    private:
    void AddThemUp();
    int a;
    int b;
  }
}

Sum.cpp
======================
namespace ns
{
  Sum::Sum(int a, int b)
  {
    this->a = a;
    this->b = b;
    AddThemUp();
  }

  void Sum::AddThemUp()
  {
     a + b;//stupid for returning nothing, just for instance
  }
}

那是在 C++ 中 我不知道如何把上面放在 C. 因为那里没有类。 如果我在头文件中声明数据成员 a & b,它们将成为全局变量。 我不喜欢全局变量。 C中有命名空间吗? 谁能帮忙?谢谢

【问题讨论】:

  • C 有可以使用的结构和函数指针。
  • C 中的所有函数都是全局的?对所有人公开?
  • @MPvaliantboy:是的。除非您在标头中声明它们并将它们设为 static(就像在 C++ 中一样)。
  • 另一个包含许多有用提示的讨论:stackoverflow.com/questions/737257/code-convert-from-c-to-c
  • 最优雅的方式是将代码发布到 StackOverflow 上,;)

标签: c++ c header


【解决方案1】:

这是从 C++ 到 C 的简单转换。此方法允许堆栈对象,就像您如何使用 ns::Sum 一样。需要注意的是,您还应该有一个释放函数来清理结构分配的所有内存。

// Main.c
// =====================

// Construction
ns_Sum sum;
ns_SumInitWithAAndB(&sum, 1, 2);

// Sum.h
// =====================

// All member variables are contained within a struct
typedef struct ns_Sum_
{
    int a;
    int b;
} ns_Sum;

// Public Methods
void ns_SumInitWithAAndB(ns_Sum *sum, int a, int b);

// Sum.c
// ======================

// Private Methods can be declared as static functions within the .c file
static void ns_SumAddThemUp(ns_Sum *sum);

void ns_SumInitWithAAndB(ns_Sum *sum, int a, int b)
{
    sum->a = a;
    sum->b = b;
    ns_SumAddThemUp(sum);
}

void ns_SumAddThemUp(ns_Sum *sum)
{
    a + b; //stupid for returning nothing, just for instance
}

【讨论】:

  • 你的意思是我可以使用一个结构来存储所有的数据成员。并将其作为某些函数的参数?
  • 这里我不知道关键字 static 的含义。和 C++ 不一样?
  • @MPvaliantboy 是的,您可以使用结构来存储数据成员。静态函数仅可用于当前 C 源文件,外部函数(默认)可用于最终链接二进制文件中的任何 C 源文件。
【解决方案2】:

不,这是 C 语言的限制之一,您没有在语言中内置单独的 namespaces。这通常是通过为名称添加前缀来完成的。至于全局变量,可以使用extern存储说明符来声明但不定义。

标题:

#pragma once

extern int ns_foo;

来源:

#include "header.h"

int ns_foo = 0;

【讨论】:

    【解决方案3】:

    其他人已经指出如何使用名称前缀来模拟命名空间。

    但是您的问题似乎还有另一个误解。只有 static 数据成员转换为 C 中的“全局”变量。其他“普通”数据成员对于 struct 的每个实例都是不同的。

    public static 成员 全局变量,所以你不能指望这会更好地工作 int C。private static 成员可以替换为 static 变量仅在您定义函数的.c 文件中声明。唯一的限制是这些对于 inline 函数不可见,就像它们对于 C++ 中的 inline 成员函数一样。

    也许应该补充的另一件事是,当你在做这样一个项目时,你可以尝试开始用 C 来思考。现代 C 有一些 C++ 中不存在的工具,C 和 C++ 的交集是一种相当受限制的语言。这些工具是,例如:

    • 指定的初始化器可以用空函数体替换构造函数
    • 在表达式中提供临时变量的复合文字
    • 指针指向 VLA(可变长度数组),可为您提供方便的向量和矩阵函数接口

    【讨论】:

      【解决方案4】:

      在 C++ 中使用 C++ 为您提供的某些功能的传统方法与大量手动工作有关:

      • 您可以为 structs 和函数使用前缀,而不是使用命名空间,例如 struct ns_Sumvoid ns_Sum_AddThemUp()
      • C 没有成员函数。因此,与其在对象上调用函数,不如将对象作为第一个参数传递,例如 void ns_Sum_SumThemUp(ns_Sum* object)
      • 制作成员private的方法是只在header中声明struct,并在源码中定义。这与合适的创建和销毁功能一起使用:

      C 头文件中的声明可能如下所示:

      typedef struct ns_Sum ns_Sum;
      ns_Sum* ns_Sum_Create();
      void    ns_Sum_Destroy(ns_Sum*);
      void    ns_Sum_AddThemUp(ns_Sum const*);
      

      对于简单的结构,使用这样的映射可以很好地工作。在 some-body-part-goes-here 中实现多态调度或处理模板的道德等价物成为皇家痛苦。我个人对在 C 中使用 C++ 的看法是使用 C++,但我意识到这种偏好并不是与所有人共享的......

      【讨论】:

      • void ns_Sum_AddThemUp() 会是void ns_Sum_AddThemUp(ns_Sum*),不是吗?
      • @JensGustedt:是的,确实如此。我纠正了这个例子。谢谢!
      • 所以现在它肯定有你的签名,类型后面有const :)
      猜你喜欢
      • 2015-03-22
      • 2021-08-24
      • 1970-01-01
      • 2015-12-06
      • 2013-02-24
      • 2015-03-03
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      相关资源
      最近更新 更多