1

重複の可能性:
C++ から C へ
のコード変換 C++ クラスから 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には名前空間がありますか?誰が助けることができますか?ありがとうございました

4

4 に答える 4

3

以下は、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
}
于 2012-09-22T20:29:28.877 に答える
0

名前プレフィックスを使用して名前空間をシミュレートする方法については、他の人が既に指摘しています。

しかし、あなたの質問には別の誤解があるようです。データ メンバーのみstaticが C の「グローバル」変数に変換されます。他の「通常の」データ メンバーは、struct.

public staticメンバーグローバル変数であるため、これがうまく機能するとは期待できません int C.メンバーは、関数を定義するファイル内でのみ宣言されている変数private staticに置き換えることができます。唯一の制限は、C++ のメンバー関数の場合と同様に、これらが関数に対して表示されないことです。static.cinlineinline

おそらく追加する必要があるもう 1 つのことは、そのようなプロジェクトを行っているときに C で考え始めることができるということです。現代の C には、C++ には存在しないツールがいくつかあります。C と C++ の共通点は、かなり制限された言語です。そのようなツールは、例えば:

  • コンストラクターを空の関数本体に置き換えることができる指定されたイニシャライザー
  • 式で一時変数を提供する複合リテラル
  • ベクトルおよび行列関数の便利なインターフェイスを提供できる VLA (可変長配列) へのポインター
于 2012-09-22T20:50:20.080 に答える
0

C++ が提供する特定の機能を C++ で使用するための従来のアプローチは、多くの手作業を必要とします。

  • 名前空間を使用する代わりに、およびなどのプレフィックスをstructおよび関数に使用します。struct ns_Sumvoid ns_Sum_AddThemUp()
  • C にはメンバー関数がありません。したがって、オブジェクトで関数を呼び出す代わりに、オブジェクトを最初のパラメーターとして渡しますvoid ns_Sum_SumThemUp(ns_Sum* object)
  • メンバーを作成する方法は、ヘッダーでprivateのみ宣言し、ソースで定義することです。structこれは、適切な create および destroy 関数と一緒に使用されます。

つまり、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*);

このようなマッピングを使用する単純な構造の場合、適切に機能します。ポリモーフィックディスパッチを実装したり、テンプレートの道徳的な同等物を処理したりすることは、身体の一部がここに行くという王室の苦痛になります。C で C++ を使用することについての私の個人的な見解は、C++ を使用することですが、この好みがすべての人に共有されているわけではないことを認識しています...

于 2012-09-22T20:32:24.413 に答える
0

namespaceいいえ、それは C の制限の 1 つです。言語に組み込まれた個別の s はありません。これは通常、名前にプレフィックスを追加することによって行われます。グローバル変数に関しては、externストレージ指定子を使用して宣言することはできますが、定義することはできません。

ヘッダ:

#pragma once

extern int ns_foo;

ソース:

#include "header.h"

int ns_foo = 0;
于 2012-09-22T19:58:16.010 に答える