我目前正在学习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;
}
答案 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
转换时,您很可能会再次重新考虑您的实施。