4

私は中規模のプロジェクトで C++ を使用したことがありますが、C で本格的なプログラミングを行ったことはありません。

この記事を読んで、どうすればクラスや例外なしで C++11 を使用できるのか疑問に思い始めました。clean Cという用語を聞いたことがあります。クリーン Cは、クラスやメタプログラミングなど、ANSI C にはない C++ 機能を使用しない C++ コードであると想定されています。

C で効果的に物事を行う方法と、C++ でそれらを行う方法に関するリソースはたくさんあります。しかし、両方の長所を活かす方法に関するリソースを見つけるのは驚くほど困難です。

私の質問は2つの部分です:

  1. 名前空間、例外、メタプログラミングなしで C++ を使用するための適切なリソースはありますか? 書籍、オープンソース プロジェクト?
  2. この単純なコードを確認してください。これは、前述の C++11 のサブセットでデータ構造と char 文字列を処理する最初の試みです。最初に頭に浮かぶのは、コードの冗長性です。あなたは何を別の方法で行いますか、またその理由は何ですか?

-

#include <cstring>

namespace addressbook {
namespace contact {

struct contact {
    char* name;
    char* email;
};

void initialize(addressbook::contact::contact* contact)
{
    contact->name = nullptr;
    contact->email = nullptr;
}

void deinitialize(addressbook::contact::contact* contact)
{
    delete[] contact->name;
    delete[] contact->email;
}

void set_name(addressbook::contact::contact* contact, char* name)
{
    delete[] contact->name;
    contact->name = new char [strlen(name) + 1];
    std::strcpy(contact->name, name);
}

void set_email(addressbook::contact::contact* contact, char* email)
{
    delete[] contact->email;
    contact->email = new char [strlen(email) + 1];
    std::strcpy(contact->email, email);
}

} // namespace contact
} // namespace addressbook

int main()
{
    namespace c = addressbook::contact;

    c::contact jimmy;

    c::initialize(&jimmy);

    c::set_name(&jimmy, const_cast<char*>("Jimmy Page"));
    c::set_email(&jimmy, const_cast<char*>("jp@example.com"));

    c::deinitialize(&jimmy);

    return 0;
}

私を憐れんでください - 私は構造プログラミングの初心者です。

なぜCだけではないのですか?

名前空間、新規/削除、標準ライブラリ アルゴリズム、Boost ライブラリ、C++11 のクールな機能など、いくつか例を挙げます。

コンストラクタ/デストラクタがないのに、なぜ新規作成/削除するのですか?

型安全のため。malloc戻り値*void

しかし、標準ライブラリは例外をスローします! そしてブーストも!

例外を使用していないという事実は、外部ライブラリからの例外を処理できないという意味ではありません。それは、システムの自分の部分で問題を別の方法で管理したいということです。

4

2 に答える 2

10

しかし、両方の長所を活かす方法に関するリソースを見つけるのは驚くほど困難です。

一つもないからです。そのようなことを行う唯一の理由は、互換性を切望しているからです。たとえば、Lua は「クリーン C」で書かれています。それについて「最高」というものはまったくありません。

それはひどい C++ コードのふりをしている単なる C コードです。C++ コードではありませんが、互換性があります。通常の C よりも「クリーンな C」の方が優れている点はありません。

編集:あなた、質問者様、WTF「クリーンC」. ソースコードを、実装も含めて、C++ としてコンパイルされる C コードにします。名前空間も、型も、定数も、何もありません。C++-with-aC-interface はまったく別のものであり、クリーンな C とはまったく関係ありません。その場合、実装で使用する C++ 機能を制限する理由はありません。

于 2012-05-10T15:24:01.170 に答える
7

最初に注意すべきことは、記事の前提を受け入れたとしても、クラスを使用しない理由はないということです。コンストラクターや割り当てなどを使用しないでください。ただし、たとえば、メンバー関数を使用しない理由はありません。

次に、あらゆる場所でポインターを使用するというわなに陥らないようにします。可能であれば、値のセマンティクスを優先する必要があります。ポインターを使用する必要がある場合は、手動のメモリ管理ではなくスマートnewポインターを使用し、(オーバーロードを使用しない限り) 例外をスローする可能性があることに注意してくださいstd::nothrow

最後に、C 関数を優先して C++ 標準ライブラリ関数を避けないでください。たとえば、使用しないでくださいstrcpystd::copyおよびその他の C++ アルゴリズムを使用します。


nullptr余談ですが、 beforeのチェックdelete[]は不要です。

于 2012-05-10T15:25:41.940 に答える