我正在做一个小项目,我发现自己处于这样的境地:
class A{}
class B : class A {
public:
void f();
int getType() const;
private:
int type;
}
class C : class A{
public:
int getType() const;
private:
int type;
}
我想知道是否有一种方法可以从type A
的对象调用f()
函数(in class B
(?
我试过了,但它说在class A
:中找不到函数f()
int main(){
vector<A*> v;
// v initialized with values of A ...
if (v->getType() == 1){ // 1 is the type of B
v->f();
}
}
A
没有f
方法,所以此代码不会编译。为了使其工作,您必须显式地向下转换指针:
B* tmp = dynamic_cast<B*>(v);
tmp->f();
首先,对于您当前的类,您不能在A*上调用getType()
。因为A的接口没有这个方法。要解决这个问题,您需要使getType
成为a中的虚拟函数,或者将type
字段移动到基类a(作为protected
(,并在子类的构造函数中初始化它。让我向你展示第一种方法,因为我认为这是一种更好的方法,因为它使这个函数的目标更加明确。
class A {
public:
virtual int getType() { return 0; } // or delete the function: ... getType() = 0;
}
class B : public A {
public:
int getType() override { return 1; }
}
使用这些类,一旦创建了B的实例,无论A*
还是B*
:指向该实例,getType((都会在该实例上调用时返回1
A *object = new B();
object->getType(); // returns 1
现在,如果您需要从B访问f()
,您可以再次将其作为一个虚拟方法添加到a的接口,或者转换为B*
。
使用虚拟方法:
class A {
public:
virtual void f() { /* a default action maybe? */ }
}
class B : public A {
public:
void f() /* override if you want */ { /* whatever this function does in B */ }
}
...
for (A *ptr : v)
ptr->f();
使用铸造:
class A {
public:
virtual int getType() { return 0; }
}
class B : public A {
public:
void f();
int getType() override { return 1; }
}
...
for (A *ptr : v)
if (ptr->getType() == 1)
dynamic_cast<B*>(ptr)->f();