如果有人能启发我,我将不胜感激:说我声明以下内容:
class A{
public:
friend class A1;
}
class A1{
public:
void f(A* a) { cout<<"Base"; };
}
class B : public A{
public:
friend class B1;
}
class B1 : public A1{
public:
void f(B* b) { cout << "Derived"; };
}
当我声明我的对象时,我这样做:
A* a;
A1* a1;
if (condition1) {
a = new A;
a1 = new A1;
}
else {
a = new B;
a1 = new B1;
}
a1 -> f(a); //outputs always 'base'
如何基于a1 -> f(a)
使B1::f()
输出condition1
?
注意:这只是我的代码的一小部分,并且类的结构必须保持不变。
答案 0 :(得分:1)
如果您希望自动完成正确的通话,则需要为 f 拥有相同的签名,并使其具有 virtual , friend >没用
#include <iostream>
using namespace std;
class A {
};
class A1{
public:
virtual void f(A* a) { cout<<"Base" << endl; };
};
class B : public A{
};
class B1 : public A1{
public:
virtual void f(A* b) { cout << "Derived" << endl; };
};
int main(int argc, char **)
{
A* a;
A1* a1;
if (argc == 1) {
a = new A;
a1 = new A1;
}
else {
a = new B;
a1 = new B1;
}
a1 -> f(a);
}
编译和执行:
pi@raspberrypi:/tmp $ g++ c.cc
pi@raspberrypi:/tmp $ ./a.out
Base
pi@raspberrypi:/tmp $ ./a.out 1
Derived
pi@raspberrypi:/tmp $
在接收器的真实类型为 virtual 的情况下确定调用方法,参数的真实类型无关紧要,仅考虑签名>
如果您需要检查 B1 :: f 的参数是 B * ,则可以执行以下操作:
#include <iostream>
using namespace std;
class A {
public:
virtual ~A(){}
};
class A1{
public:
virtual void f(A* a) { cout<<"Base" << endl; };
};
class B : public A{
public:
virtual ~B(){}
};
class B1 : public A1{
public:
virtual void f(A* b) {
cout << "Derived, "
<< ((dynamic_cast<B*>(b) == NULL)
? "invalid call, needed a B*"
: "valid call with a B*")
<< endl;
}
};
int main(int argc, char **)
{
A* a;
A1* a1;
switch (argc) {
case 1:
a = new A;
a1 = new A1;
break;
case 2:
a = new B;
a1 = new B1;
break;
default:
a = new A;
a1 = new B1;
}
a1 -> f(a);
}
编译和执行:
pi@raspberrypi:/tmp $ g++ c.cc
pi@raspberrypi:/tmp $ ./a.out
Base
pi@raspberrypi:/tmp $ ./a.out 1
Derived, valid call with a B*
pi@raspberrypi:/tmp $ ./a.out 1 2
Derived, invalid call, needed a B*
我在A和B中添加了虚拟析构函数,以便能够使用dynamic_cast
或者如果您想在 B1 :: f 的参数不是 B * 的情况下使用基本情况:
class B1 : public A1{
public:
virtual void f(A* a) {
B * b = dynamic_cast<B*>(a);
if (b == NULL)
A1::f(a);
else {
cout << "Derived" << endl;
// use of b known as a B*
}
}
};
编译和执行:
pi@raspberrypi:/tmp $ g++ c.cc
pi@raspberrypi:/tmp $ ./a.out
Base
pi@raspberrypi:/tmp $ ./a.out 1
Derived
pi@raspberrypi:/tmp $ ./a.out 1 2
Base