1

基本的なものが欠けているかどうかはわかりません。しかし、コンパイラがこのコードのエラーを生成している理由を理解できません。

class A
{
};

class B
{
public:
    B();
    A* get() const;

private:
    A* m_p;
};

B::B()
{
    m_p = new A;
}

A* B::get() const
{
    //This is compiling fine
    return m_p;
}

class C
{
public:
    A* get() const;
private:
    A m_a;
};

A* C::get() const
{
   //Compiler generates an error for this. Why? 
    return &m_a;
}

編集:コンパイラエラーは次のとおりです:エラーC2440:'return':'const classA*'から'classA*'に変換できません変換は修飾子を失います

4

7 に答える 7

12

const関数シグネチャのは、オブジェクトのメンバーを変更できないことをコンパイラに通知します。それでも、メンバーへの非ポインターを返すため、constその約束の違反が許可されます。

あなたのクラスBでは、メンバーへのポインターを返さず、そのコピーを返すので、約束をしません/約束しません(そしてメンバーはたまたまポインターです)。

于 2009-02-09T13:28:58.117 に答える
3

これは、const関数からメンバーへの非constポインターを返しているためです。

最初の部分は、メンバーポインターのコピーを返すために機能します。したがって、これはget関数の定数に違反しません。

class B
{
public:
    B();
    A* get() const;

private:
    A* m_p;
};

A* B::get() const
{
    //This is compiling fine
    return m_p;
}

しかし、次のビットはコンパイルエラーを生成します(gcc 4で)

testfile.cpp:37:エラー:「constA*」から「A*」への無効な変換</p>

const get関数は、m_aへの非constポインターを返すことにより、m_aに非constアクセスを提供しているためです。

class C
{
public:
    A* get() const;
private:
    A m_a;
};

A* C::get() const
{
   //Compiler generates an error for this. Why?
    return &m_a;
}
于 2009-02-09T13:28:15.873 に答える
1

返されるポインタはconstではないためです。これに変更します:

class C
{
public:
    const A* get() const;
private:
    A m_a;
};

const A* C::get() const
{
    //Compiler generates an error for this. Why? 
    return &m_a;
}

C :: get()がAへのconstポインタを返すことに注意してください。

于 2009-02-09T13:30:25.307 に答える
0

マークされたメンバー関数はconst、非定数参照またはプライベート変数へのポインターを返すことはできません。コンパイラがこれを許可した場合、クラス外の誰もが前述のプライベート変数を変更できconst、関数の修飾子は意味を失います。

于 2009-02-09T13:30:26.053 に答える
0

この問題は、より簡単な例で説明できます。

class MyClass {
public:
    int *get() const;
private:
    int value;
};

int *MyClass::get() const {
    return &value;
}

ではMyClass::get() constvalueタイプはconst intです。逆参照すると、 が得られconst int *ます。その型は安全に (暗黙的に) にキャストできませんint *。問題を解決するには、get()returnを使用してくださいconst int *

于 2009-02-09T13:31:11.387 に答える
0
A* C::get() const
{
   //Compiler generates an error for this. Why? 
    return &m_a;
}

get() は const 関数であるため、コンパイラは参照するすべてのメンバー変数を const として扱います。このようなメンバーのアドレスを取得すると、const へのポインターが得られます。しかし、関数は非 const ポインターを返しています。コードを次のように変更する必要があります

const A* C::get() const
{
    return &m_a;
}
于 2009-02-09T13:33:38.603 に答える
0

基本的に前に const を追加するだけで、

const A* C::get() const
{
   //Compiler generates an error for this. Why? 
    return &m_a;
}

次に、アクセスしたい場合は、基本的に次のようにします。

C something;

const A* a = something.get();

しかし、あなたのプログラムは私にはほとんど意味がありません。

IMO、次のことを行うのが最も理にかなっています:

class A{
};

class C : public A
{
};

そうすれば、A のインスタンスを返す「get」を作成する必要がなくなります。

于 2009-02-09T16:08:44.847 に答える