9

私はたまたま次のようなコードを書きます:

class a
{
    public:
        a() {}
};


int main()
{
    a *a = new a;        // line 10
    a a;                 // line 11
    return 0;
}

g++ エラー:

2.c: In function ‘int main()’:
2.c:10:16: error: expected type-specifier before ‘a’
2.c:10:16: error: cannot convert ‘int*’ to ‘a*’ in initialization
2.c:10:16: error: expected ‘,’ or ‘;’ before ‘a’
2.c:11:7: error: expected ‘;’ before ‘a’

10行目で「a *a」を「a *b」に変更すると、g ++が満足することがわかりました。これが良いコードです:

class a
{
    public:
        a() {}
};


int main()
{
    a *b = new a;
    a a;
    return 0;
}

元のコードがコンパイルされない理由と「修正」がどのように機能するかがわかりません。

何か案が?

4

4 に答える 4

14

詳細については、 Vaughn の回答を参照してください。ただし、変数ではなくクラスを使用するように指定すると、この問題を解決できます。

class a
{
    public:
        a() {}
};


int main()
{
    a *a = new class a;
    return 0;
}

また

int main()
{
    class a a; // although the class word isn't needed here
    return 0;
}

説明

C の時代には、構造体は独自の名前空間に配置されていました。C++ でも同様のことが起こりますが、同じ名前のローカル関数または変数がない限り、クラス名は名前空間の外で使用できます。

Aクラス/構造体と変数/関数の両方に同じ名前を使用する場合は、 /キーワードAを使用する必要があります。これは、コンパイラが以降のすべての出現を構造体/クラスではなく変数/関数として解釈するためです。structclassA

于 2012-11-11T16:51:29.277 に答える
5

宣言している変数名が表示されるとすぐに、アクセス可能になります。

したがって、このコードでは:

a *a = new a;
           1

ポイント1ではa、クラスaではなく変数aを参照しています。

代わりにこれを行う場合:

a *b = new a;
a a;

bは別の名前なので問題ありません。

于 2012-11-11T16:49:05.260 に答える
1

G ++は識別子を見つけa、クラス名ではなくポインターを意味すると考えます。あなたの行a *a = new a;は次と同じです:

a *a;
a = new a;

aここで 2 行目では、クラス名ではなくポインターとして既に定義されているため、G++ は混乱します。

もう 1 つの行a a;は 1 つのステートメントにすぎないため、機能します。

CamelCase一般に、クラス(各単語の最初の文字は大文字) に名前を付け、インスタンス (変数名)lower_caseまたはlowerCamelCase(場合によっては と呼ばれる) に名前を付けることをお勧めしますmixedCase

于 2012-11-11T16:51:45.690 に答える
0

typedef を使用して、型に一時的にエイリアスを設定できます。

class a;
typedef a _a;
_a a;
void Get(_a a);
于 2013-02-21T23:31:05.463 に答える