以前は、この質問に対する答えは「100%」だと思っていましたが、最近、再考する価値のある例を指摘されました。自動保存期間を持つオブジェクトとして宣言された C 配列を考えてみましょう。
int main()
{
int foo[42] = { 0 };
}
ここで、 の型foo
は明らかにint[42]
です。代わりに、次のケースを検討してください。
int main()
{
int* foo = new int[rand() % 42];
delete[] foo;
}
ここで、 の型はfoo
ですが、コンパイル時に式によって作成されたオブジェクトint*
の型をどのように判断できますか? (強調は、式によって返されるポインターについて話しているのではなく、式によって作成された配列オブジェクトについて話しているという事実を強調することを目的としています)。new
new
new
new
これは、C++11 標準のパラグラフ 5.3.4/1 が式の結果について指定しているものです。
[...] new-expressionによって作成されたエンティティには、動的ストレージ期間 (3.7.4) があります。[ 注: そのようなエンティティの有効期間は、必ずしもそれが作成されたスコープに制限されるわけではありません。—終わりの注] エンティティが非配列オブジェクトの場合、new-expressionは作成されたオブジェクトへのポインターを返します。配列の場合、new-expression は配列の最初の要素へのポインターを返します。
私は以前、C++ ではすべてのオブジェクトの型がコンパイル時に決定されると考えていましたが、上記の例はその信念を反証しているようです。また、パラグラフ 1.8/1:
[...] オブジェクトのプロパティは、オブジェクトの作成時に決定されます。オブジェクトには名前を付けることができます (条項 3)。オブジェクトには、その寿命 (3.8) に影響を与える保存期間 (3.7) があります。オブジェクトには型 (3.9) があります。[...]
だから私の質問は:
- 最後に引用した段落の「プロパティ」は何を意味していますか? 明らかに、オブジェクトの名前は、「オブジェクトが作成されたときに」決定されるものとしてカウントすることはできません-ここで「作成された」が私が考えているものとは異なることを意味しない限り。
- 実行時にのみタイプが決定されるオブジェクトの例は他にありますか?
- C++ が静的に型付けされた言語であると言うのは、どの程度正しいのでしょうか? というか、この点で C++ を分類する最も適切な方法は何ですか?
誰かが上記の点の少なくとも 1 つについて詳しく説明できれば素晴らしいことです。
編集:
標準は、new
式が実際に配列 objectを作成することを明確にしているようです。パラグラフ 5.3.4/5 による ( Xeo 提供):
割り当てられたオブジェクトが配列の場合(つまり、noptr-new-declarator構文が使用されるか、new-type-idまたは type-idが配列型を示す)、new-expression は最初の要素へのポインターを生成します ( any) の配列。[注: と の両方が type
new int
を持ち、 の型は--end note ] noptr-new-declarator のattribute - specifier-seqは、関連付けられた配列 type に属します。new int[10]
int*
new int[i][10]
int (*)[10]