这是this的后续问题。现在我有了这段代码:
class A
{
protected:
string name;
public:
A(string a) {name = a;}
virtual string getName() {return "A name: " + name;}
};
class B: public A
{
public:
using A::A;
string getName() {return "B name: " + name;}
string newMethod() {return "B name new: " + name;}
};
void print_name(A & obj)
{
// HOW to check if obj is B, and call newMethod then.
cout << obj.newMethod() << endl; // THIS LINE HAS ERROR below
}
int main()
{
A a("a");
B b("b");
print_name(a);
print_name(b);
return 0;
}
我收到错误&#39; A类&#39;没有名为&#39; newMethod&#39; 的成员。我知道它因为新方法只在B中。
但是如何检查print_name中的obj是A还是B,并且只有当obj是B时才调用newMethod?
答案 0 :(得分:2)
这是技巧,请使用dynamic_cast
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
dynamic_cast只能用于指针和对类的引用(或使用void *)。其目的是确保类型转换的结果指向目标指针类型的有效完整对象。
答案 1 :(得分:2)
这是使用虚拟方法的方法:
class B: public A
{
public:
...
// new implementation of virtual method, old signature
string getName() {return "B name new: " + name;}
};
void print_name(A & obj)
{
cout << obj.getName() << endl;
}
答案 2 :(得分:2)
嗯,这不是一个很棒的设计。但你可以写:
cout << dynamic_cast<B &>(obj).newMethod() << endl;
如果obj
实际上不是B
,则会抛出异常。如果您不想要异常,那么您可以转换为指针:
B *ptr = dynamic_cast<B *>(&obj);
if ( ptr )
cout << ptr->newMethod() << endl;
答案 3 :(得分:0)
由于newMethod未在A类中声明,因此失败,显然A类的对象引用将找不到名为newMethod的方法。 要实现您的目标,您应该使用RTTI的概念使用typeof运算符。
答案 4 :(得分:0)
您可以使用动态投射:
void print_name(A & obj)
{
B * b = dynamic_cast<B*>(&obj);
if (b != nullptr) {
cout << b->newMethod() << endl;
} else {
cout << obj.getName() << endl;
}
}