向派生 class 添加方法并从基指针调用它
adding method to derived class and calling it from base pointer
假设我有以下 class 层次结构:
class A
{
public:
virtual ~A();
};
class B : public A
{};
class AUser
{
public:
virtual ~AUser();
protected:
A* m_pA;
};
class BUser : public AUser
{};
现在我想向 B
添加一个与 A
无关的方法,并且只会从 BUser
.
调用
class B : public A
{
public:
void addedFunctionality()
{
// do something
}
};
要调用添加的方法,我有两个选择:
给A添加一个空方法:
class A
{
public:
virtual ~A();
void addedFunctionality()
{
// do nothing
}
};
class BUser : public AUser
{
void useB()
{
m_pA->addedFunctionality();
}
};
使用向下转换调用添加的方法:
class BUser : public AUser
{
void useB()
{
static_cast<B*>(m_pA)->addedFunctionality();
}
};
我知道应该避免向下转换,但我不喜欢第一个选项,因为它无缘无故地膨胀了 A
的代码。
还有其他设计方案吗?
最简单的解决方案如下所示(Ulrich Eckhardt 也建议):
class AUser
{
public:
AUser(A* a)
{
m_pA = a;
}
protected:
A* m_pA;
};
class BUser : public AUser
{
public:
BUser(B* b) : AUser(b)
{
m_pB = b;
}
void useB()
{
m_pB->addedFunctionality();
}
protected:
B* m_pB;
};
不太干净,但你也可以考虑这个:
class BUser : public AUser
{
public:
BUser(B* b) : AUser(b)
{
}
void useB()
{
getB()->addedFunctionality();
}
protected:
B *getB()
{
return dynamic_cast<B*>(m_pA);
}
};
假设我有以下 class 层次结构:
class A
{
public:
virtual ~A();
};
class B : public A
{};
class AUser
{
public:
virtual ~AUser();
protected:
A* m_pA;
};
class BUser : public AUser
{};
现在我想向 B
添加一个与 A
无关的方法,并且只会从 BUser
.
class B : public A
{
public:
void addedFunctionality()
{
// do something
}
};
要调用添加的方法,我有两个选择:
给A添加一个空方法:
class A { public: virtual ~A(); void addedFunctionality() { // do nothing } }; class BUser : public AUser { void useB() { m_pA->addedFunctionality(); } };
使用向下转换调用添加的方法:
class BUser : public AUser { void useB() { static_cast<B*>(m_pA)->addedFunctionality(); } };
我知道应该避免向下转换,但我不喜欢第一个选项,因为它无缘无故地膨胀了 A
的代码。
还有其他设计方案吗?
最简单的解决方案如下所示(Ulrich Eckhardt 也建议):
class AUser
{
public:
AUser(A* a)
{
m_pA = a;
}
protected:
A* m_pA;
};
class BUser : public AUser
{
public:
BUser(B* b) : AUser(b)
{
m_pB = b;
}
void useB()
{
m_pB->addedFunctionality();
}
protected:
B* m_pB;
};
不太干净,但你也可以考虑这个:
class BUser : public AUser
{
public:
BUser(B* b) : AUser(b)
{
}
void useB()
{
getB()->addedFunctionality();
}
protected:
B *getB()
{
return dynamic_cast<B*>(m_pA);
}
};