将它转换为基类指针是否安全?

时间:2012-06-15 21:57:08

标签: c++ pointers polymorphism

我目前正在学习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 个答案:

答案 0 :(得分:6)

是的,这是安全的,但也没有必要。 :)

转换是隐含的,因此无需强制转换。

CUser CUserCounter(至少在您的设计中),因此指向CUser的指针也是指向{{1}的指针}。

答案 1 :(得分:3)

我想讨论一个比问题中明确的问题更大的问题。

你有CUser来自CUserCounter。这似乎是一个错误,因为用户不是计数器。在这种情况下,你应该有一个 has-a 关系--CUser对象应该包含一个CUserCounter对象,而不是一个。

要回答这个问题,派生类可以访问它想要的基类的任何成员。不需要铸造,实际上铸造可以隐藏一些令人讨厌的问题 - 除非绝对必要,否则避免使用。

答案 2 :(得分:2)

通常不建议将成员变量公开。而是将它们设为私有并提供公共getter和/或setter方法。

如果必须从派生类访问变量,请将其保护为

原因是成员变量表示对象的状态,并且不建议允许直接修改,因为它允许以破坏类的基础逻辑的方式更改状态(想想String类:if你可以直接修改持有字符串大小的缓存的变量,如果字符数组没有相应地重新调整大小,那么可能会对进一步使用对象产生影响。

对于this指针:在大多数情况下,您不需要显式使用它,它的使用可以从上下文中解决。但是,如果成员函数中的成员变量和参数具有相同的名称,则该参数将隐藏成员变量,您必须使用this才能访问它。 (当派生类的成员函数隐藏父函数声明时,类似的效果会起作用)

您也可以通过this访问类父类的受保护成员和公共成员,但如上所述,您通常不需要使用它。此外,在这些情况下,不需要转换为(指向)父类型

答案 3 :(得分:0)

在我看来,这种转换不仅是不必要的,而且也是不优雅的。有人说很明显,如果从某个类继承,你可以使用一些字段/方法。您不仅要编写一些不必要的代码,还要使您的方法不易读取并且难以维护。编译器可能会优化此类代码并删除其他指令,因此可能没有效率成本(但这只是我的假设)。我坚信,当您认为有必要进行this转换时,您很可能会再次重新考虑您的实施。