0

私は現在C++を学んでいますが、今回はポインターをいじり、thisポインターとポリモーフィズムを研究していました。私の質問は、以下の変換は安全ですか、基本的には「公開」のためにクラスからm_uConnectedUsers直接アクセスできることを知っていCUserますが、それが必要になる場合があります。あなたの専門家の意見を知りたいです。それ。

#include <windows.h>
#include <iostream>

using namespace std;


class CUserCounter
{
public:
    CUserCounter();
    virtual ~CUserCounter(){};

    BOOL m_bEmpty;
    u_long m_uConnectedUsers;
};

CUserCounter::CUserCounter()
{
    m_bEmpty = TRUE;
    m_uConnectedUsers = 0;
}

class CUser : public CUserCounter
{
public:
    CUser(LPCTSTR szName, BOOL bConnected, BOOL bChatting = FALSE );
    virtual ~CUser(){};

    BOOL m_bConnected;
    BOOL m_bIsChatting;
    TCHAR szCharName[32];

    bool IncreaseMoverMeter( unsigned uMeters );
};

CUser::CUser( LPCTSTR szName, BOOL bConnected, BOOL bChatting )
{
    if( szName )
    {
        if( strlen( szName ) > 30 )
            strcpy( szCharName, "Invalid" );
        else
            strcpy( szCharName, szName );
    }
    m_bConnected = bConnected;
    m_bIsChatting = bChatting;
}

bool CUser::IncreaseMoverMeter( unsigned uMeters )
{
    //is it safe? how does it works
    CUserCounter* pUserCounter = (CUserCounter*)this;
    if( pUserCounter )
    {
        pUserCounter->m_uConnectedUsers++;
        return true;
    }
    return false;
}


int main( int argc, char *argv[] )
{             
    CUser *pUser = new CUser( "Jonh", FALSE );
    std::cout << pUser->IncreaseMoverMeter( 4 );

    system("pause>nul");
    return EXIT_SUCCESS;
}
4

4 に答える 4

6

はい、安全ですが、必須ではありません。:)

変換は暗黙的であるため、キャストする必要はありません。

CUser CUserCounter(少なくとも設計では) であるため、 a へのポインターは へのCUserポインターでもありますCUserCounter

于 2012-06-15T21:59:16.977 に答える
3

質問で明示されている問題よりも大きな問題について話し合いたいと思います。

CUserCounter から派生した CUser があります。ユーザーはカウンターではないため、これは間違いのようです。この場合、has-a関係が必要です。CUser オブジェクトには、CUserCounter オブジェクトではなく、CUserCounter オブジェクトが含まれている必要があります。

この質問に答えるために、派生クラスは必要な基本クラスの任意のメンバーにアクセスできます。キャストは必要ありません。実際、キャストはいくつかの厄介な問題を隠す可能性があります。どうしても必要な場合を除き、キャストは避けてください。

于 2012-06-15T22:02:15.500 に答える
2

通常、メンバー変数を公開することはお勧めしません。代わりに、それらをプライベートにして、パブリックの getter および/または setter メソッドを提供してください。

派生クラスから変数にアクセスする必要がある場合は、保護してください

この理由は、メンバー変数がオブジェクトの状態を表し、直接変更を許可することは推奨されません。これは、クラスの基になるロジックを壊す方法で状態を変更できるためです (String クラスを考えてください: 直接変更できる場合文字列のサイズのキャッシュを保持する変数を変更すると、文字配列のサイズもそれに応じて変更されない場合、オブジェクトをさらに使用すると大混乱を招く可能性があります)

ポインターに関してはthis、ほとんどのコンテキストで明示的に使用する必要はありません。その使用はコンテキストから判断できます。ただし、メンバー関数に同じ名前のメンバー変数とパラメーターがある場合、パラメーターはメンバー変数を非表示にするため、thisアクセスするには を使用する必要があります。(派生クラスのメンバー関数が親の関数宣言を隠している場合にも、同様の効果が発揮されます)

を介して、クラスの親クラスの保護されたメンバーとパブリック メンバーにもアクセスできますthisが、上記のように、通常は使用する必要はありません。また、これらの場合、親の型への (ポインターへの) 変換は必要ありません。

于 2012-06-15T22:01:06.660 に答える
0

私の意見では、そのような変換は不要であるだけでなく、エレガントでもありません。誰かが言ったように、あなたがいくつかのクラスから継承するなら、あなたはいくつかのフィールド/メソッドを利用できることは明らかです。不必要なコードを書くだけでなく、メソッドを読みにくくし、保守を難しくします。コンパイラはおそらくそのようなコードを最適化し、追加の命令を削除するので、効率のコストは発生しないかもしれません(しかしそれは私の仮定にすぎません)。変換が必要だと思ったら、thisもう一度実装を考え直さなければならない可能性が高いと思います。

于 2012-06-15T22:15:12.797 に答える