我有一个被子类化的工具。报告了一个错误,其中子类从它不应该采用的超类中获取了一个值:
mySuperclass.SetMyVar()
is being called for a subclass object.
如果我做不到
SetMyVar
private
– 因为它在两个类发生的初始化中被调用 – 我能否使行为取决于这是超类项目还是子类项目?
建议的修复——为子类提供
SetMyVar()
——如果再次派生超类,则会出现维护问题。
[不过,如果我使用了
b.SetMyVar()
但它没有这样做,那么我可能还有另一个 bug 需要解决......也许子类实现是正确的。]
像这样的东西:
class A
{
public:
A() {myVar = 20; }
void SetMyVar(int val)
{
//eg (typeid (this).name() == "class A*") // doesn't work
//eg (dynamic_cast <A*>(this)) // doesn't work
[something here to make it happen for only objects of type superclass]
{
myVar = val;
}
}
int myVar;
};
class B : public A
{
public:
B() { myVar = 10; }
};
int main(...)
{
A a;
B b;
a.SetMyVar(2);
b.SetMyVar(3); < -- this should not set myVar
std::cout << a.myVar << " : " << b.myVar;
return 0;
}
如评论中所述,如果要动态区分基类和派生类(例如使用
typeid
),那么您的基类必须具有虚函数。
最简单的添加是(默认)虚拟析构函数;然后可以使用
typeid()
比较来发现派生类对象对基类函数的调用:
#include <iostream>
#include <typeinfo>
class A {
public:
A() { myVar = 20; }
virtual ~A() = default; // This makes the class polymorphic
void SetMyVar(int val)
{
// if (typeid(this) == typeid(A*)) {// Wrong: "this" is always of type A* here!
if (typeid(*this) == typeid(A)) {
myVar = val;
}
}
int myVar;
};
// Remaining code as you have it ...
还请注意,我的代码对
dereferenced
typeid
指针(即调用函数的实际对象)进行 this
检查。 typeid
对 actual this
指针的检查将始终产生指向定义代码的类的指针。