0

動的に割り当てたメモリがどこにも向いていないことを保証しようとしていました。

私は次のことを試しました

template<typename T>
[...something here...]
T *mem = new T[size];

for ( int i=0; i<size; i++ )
{
    (mem+i) = NULL;
}  
[...something else there...]

人が書くことができるように

int *pInt = new int;
pInt = NULL;

しかし、上の例memでは「左辺値」ではないため、それは機能しませんか?

ヒープに 1 つのタイプ固有のメモリを動的に割り当てる場合にのみ、これが当てはまるように見えるのはなぜですか?

さらに、テンプレート関数を使用すると、1 つの奇妙なことが起こります。

template<typename T>
[...something here...]
T mem = new T[size];

for ( int i=0; i<size; i++ )
{
    *(mem+i) = NULL;

    /* or the equivalent
    mem[i] = NULL;
    */
}  
[...something else there...]

NULL基本的に何でもかまいません変数またはオブジェクトに(基本的にはint値 0)を割り当てるにはどうすればよいでしょうか? それは変数かもしれませんがint、うまくいくでしょう。しかし、テンプレート関数を で呼び出したらどうなるでしょうかstd::string。まったく機能しないはずですよね?では、なぜこのようなものを書くことが合法であるように見えるのでしょうか?

ジェネリックをプログラミングする自由ですが、間違った型でジェネリック関数を呼び出さないように注意する責任もありますか?

4

2 に答える 2

1

しかし、上の例の「mem」は「左辺値」ではないため、それは機能しませんか?

確かに、一時ポインタを再割り当てしようとしていますmem+i。それは意味がありません。mem[i]おそらく、配列メンバー (または*(mem+i)) を何かに設定したいでしょう。ただし、ポインター型であると想定されている場合をNULL除き、おそらくそうではありません。T

単一のオブジェクトの例では、割り当てられたオブジェクトへの唯一のポインターを再割り当てしています。したがって、オブジェクトを使用または削除する方法はありません。

基本的に何でもかまいません変数またはオブジェクトに NULL (基本的に int 値 0 ) を割り当てるにはどうすればよいでしょうか?

C++11 より前では、有効なヌル ポインター定数 (したがって、マクロの有効な展開のみNULL) は値がゼロの整数定数だけだったためです。コードは次のように展開されます

*(mem+i) = 0;

これは多くのタイプに有効です。最近では、 にNULL拡張される (または拡張されない) 可能性がありnullptr、その場合、ポインター型に対してのみ有効になります。

しかし、std::string でテンプレート関数を呼び出したらどうなるでしょうか。まったく機能しないはずですよね?

std::stringたとえば、C スタイルの文字列へのポインターを使用するコンストラクターと代入演算子があります。

std::string hello = "Hello, world!";

これらはヌル ポインターを受け取ることもでき、未定義の動作が発生します。

于 2014-03-06T19:18:24.530 に答える
0

あなたのコードは次のとおりです。

for ( int i=0; i<size; i++ )
{
  (mem+i) = NULL;
}

この場合(mem+i)は一時的な結果であり、右辺値と呼ばれます。右辺値は一時的なものであるため、値を割り当ててはなりません。左辺値にのみ値を割り当てることができます。(ところで、これはあなたがやりたいことではないと思います:ポインターに格納されているアドレス値ではなく、ポインターが示すメモリを変更したいと思います)

for ( int i=0; i<size; i++ )
{
  mem[i] = NULL;
 *(mem+i) = NULL;
}

この場合、一時的な結果も計算されますが (どちらの場合もmem+i)、正しいメモリをアドレス指定するために使用されます。したがって、どちらの場合も、指されるメモリは左辺値です。

テンプレートを使用する場合は、これらがテンプレートであることを覚えておく必要があります ;-) テンプレートがどこにも使用されていない場合、テンプレート コードはコンパイルされません。また、使用する場合は、テンプレート引数として使用する変数/クラスの種類によって異なります。

このコードを書くことができます:

template<typename T>
void func( T a)
{
  a.foo = "bar";
  a.my_func( 3.14);
}

このコードは奇妙に見えますが、 を割り当てることができるメンバー変数/オブジェクトと、名前でオーバーロードされたメンバー関数または関数ポインターまたはオブジェクトを持つa任意の構造体またはクラスのそれぞれに対してコンパイルされます。fooconst charoperator ()my_func

于 2014-03-06T19:36:56.733 に答える