8

大まかに言えば、const unsigned char の配列を保持するクラスがあります。このクラスのオブジェクトは、(ヒープ上での) 配列の構築も処理する特別なファクトリ関数によって作成されます。ファクトリ関数でオブジェクトが作成されると、配列へのポインタが与えられます。配列はコピーされず、オブジェクトは指定されたポインターを使用するだけです。破棄すると、配列が占有していたメモリのチャンクの割り当てが解除されます。

class Foo
{
private:
    const unsigned char* array;
    size_t size;

public:
    Foo(const unsigned char* array, size_t size) : array(array), size(size) {}
    ~Foo() {delete [] array;}
};

Foo* factoryFunction(const void* data, size_t size)
{
    unsigned char* array = new unsigned char[size];
    memcpy(array, data, size);
    return new Foo(array, size);
}

new []を返すため、副作用があるかどうか疑問に思いますunsigned char *が、delete []が呼び出されconst unsigned char *ます。ただし、セグメンテーション違反は発生しません。

4

3 に答える 3

1

まず第一に、std::vector<unsigned char>代わりに使用する必要がある C++ でこの種の配列を使用しないようにする必要があります。

constキーワードについて。コンパイラーとコードを読む人に、このメンバー/変数/パラメーターを変更してはならないことを伝えるだけです。

そこへのポインターでは、constキーワードの位置が重要です。

編集:この部分を借りたグレイソンの答えを見つけました
constキーワードは、左側の部分を定数としてマークします(最初にある場合は、その直後のタイプのためconst unsigned charでありunsigned char const、等しいです)

ポインターを const としてマークするには、次のようにします (内容は変更可能です)。

unsigned char * const aConstantPointerToAMutableContent;

コンテンツを const としてマークするには、次のようにします。

const unsigned char * aPointerToAConstantContentA;
unsigned char const * aPointerToAConstantContentB;

両方を定数としてマークするには:

const unsigned char * const aConstantPointerToAConstantContent;

これは、データに対して何が行われ、何が行われていないかを明確にするためのヒントです。パラメータがconst unsigned char * の場合、ユーザーは、このコンテンツが渡されても変更されないことがわかります。

何かが変更可能な場合、constキーワードは単なるマークであるため、サイズ自体には影響しdeleteません。( Orbit の Lightness Racesの回答とコメント、および「Is const_cast safe?」を参照してください)。

しかし、あなたのコードで気に入らないのは、コンストラクターが公開されていることです。直接呼び出すこともできますが、パラメーターが であるためconst unsigned char* array、クラスがコンテンツを変更したり、破壊時に削除されたりするとは思わないでしょう。(オブジェクトを直接作成すると、ファクトリを使用するのとは異なる方法で動作するとは思いません。)

したがって、ファクトリ メソッドをstaticクラスのメソッドとして作成し、コンストラクタを作成しprotectedます。

于 2013-04-19T09:01:46.920 に答える
1

「unsigned char」(または任意のデータ型)の「const」性により読み取り専用データになるため、問題はありません。

削除で「[]」を使用すると、配列を削除する必要があることがわかります。

「delete」と「delete []」の背後にあるものを理解するには、これを読んでください。

于 2013-04-19T08:13:20.907 に答える