2

ArduinoUnitユニット テスト ライブラリでは、TestSuite に名前を付けるメカニズムを提供しました。ライブラリのユーザーは、次のように記述できます。

TestSuite suite("my test suite");
// ...
suite.run(); // Suite name is used here

これは想定される使用方法です。TestSuite の名前は文字列リテラルです。ただし、見つけにくいバグを防ぐために、次のようなさまざまな用途に対応する必要があると感じています。

char* name = (char*) malloc(14);
strcpy(name, "my test suite");
TestSuite suite(name);
free(name);
// ...
suite.run(); // Suite name is used here

そのため、次のように TestSuite を実装しました。

class TestSuite {
public:
  TestSuite(const char* name) {
    name_ = (char*) malloc(strlen(name) + 1);
    strcpy(name_, name);
  }

  ~TestSuite() {
    free(name_);
  }

private:
  char* name_;
};

コンストラクターでのメモリ割り当てエラーの処理に失敗するという問題はさておき、次のようにポインターをメンバー変数に単純に割り当てることをお勧めします。

class TestSuite {
public:
  TestSuite(const char* name) : name_(name) {
  }

private:
  const char* name_;
};

動的メモリ割り当てを廃止できるように、インターフェイスを変更して「正しく」使用するようにする方法はありますか?

4

6 に答える 6

2

オーバーロードされたコンストラクターを 2 つ提供するとどうなるでしょうか。

TestSuite(const char* name) ...
TestSuite(char* name) ...

で呼び出された場合const char*、コンストラクターは、文字列が消えないと仮定して、ポインターのコピーを作成できます。で呼び出された場合char*、コンストラクターは文字列全体のコピーを作成できます。

が実際に動的に割り当てられているconst char*場合でも、コンストラクターにa を渡すことで、このメカニズムを覆すことができることに注意してください。nameただし、目的にはこれで十分な場合があります。

APIでこの手法が使用されているのを実際に見たことがないことに注意してください.

于 2009-06-22T19:48:15.093 に答える
1

まあ、すべてのメモリ割り当てを処理する std::string を使用できます

class TestSuite {
public:
  TestSuite(const std::string &name):name_(name) {
  }

  ~TestSuite() {
  }

private:
  std::string name_;
};

編集:回避したいのがmalloc()の呼び出しである場合、これを行うことができます:

class TestSuite {
public:
  TestSuite(const char *name){
    memcpy(name_, name, min(16, strlen(name));
  }

private:
  char name_[16];
};

ただし、これにより一部のメモリが浪費され、組み込みプラットフォームで問題になる可能性があります。

于 2009-06-22T14:15:35.267 に答える
1

ドキュメンテーション。例えば、

/**
* Test suite constructor.
* @param name test suite name cstring, shared
*/
TestSuite(char const *name) {
// ...

共有ポインタは、指定されたオブジェクトがこのオブジェクトの存続期間中に生きている必要があることを意味します。

于 2009-06-22T14:18:13.250 に答える
1

char name[XYZ] TestSuiteのメンバー (名前を快適に表示するのに十分な大きさの XYZ を持つ) を用意strncpyし、文字列をコピーするために使用します (最大長は XYZ-1 です)。

于 2009-06-22T15:08:08.827 に答える
-1

コンストラクターで文字列リテラルまたは char* を受け取ることができる素敵な C++ 文字列クラスがあるのに、なぜ char* と malloc を使用しているのですか?

于 2009-06-22T14:14:17.127 に答える
-1

std::string を使用できますか? あなたはそれをstd::string name_持っていて、STLにメモリ割り当てを任せることができます..

class TestSuite {
    public:
      TestSuite(const char* name) : name_(name) {}

      ~TestSuite() {}

    private:
      std::string name_;
};

を含めることを忘れないでください<string>

参照

于 2009-06-22T14:15:09.090 に答える