我想根据子类A
的类型检查超类B
的类型(使用超类A
内的方法,以便B
将继承它。)
这就是我认为的诀窍(即使用前向声明):
#include <iostream>
#include <typeinfo>
using namespace std;
class B;
class A {
public:
int i_;
void Check () {
if (typeid (*this) == typeid (B))
cout << "True: Same type as B." << endl;
else
cout << "False: Not the same type as B." << endl;
}
};
class B : public A {
public:
double d_;
};
int main () {
A a;
B b;
a.Check (); // should be false
b.Check (); // should be true
return 0;
}
但是这段代码不能编译。我得到的错误是:
main.cc: In member function ‘void A::Check()’:
main.cc:12: error: invalid use of incomplete type ‘struct B’
main.cc:6: error: forward declaration of ‘struct B’
我怎么能解决这个问题?
答案 0 :(得分:3)
我认为您尝试解决的问题可以通过虚拟方法更好地处理:
class A
{
public:
virtual bool Check() { return false; };
}
class B : public A
{
public:
// override A::Check()
virtual bool Check() { return true; };
}
基类A中的方法不应该知道对象是“真的”是A还是B.这违反了基本的面向对象设计原则。如果在对象是B时需要更改行为,那么应该在B中定义该行为并由虚方法调用处理。
答案 1 :(得分:1)
将Check()的定义移出A:
的主体#include <iostream>
#include <typeinfo>
using namespace std;
class B;
class A {
public:
int i_;
void Check ();
};
class B : public A {
public:
double d_;
};
void A::Check () {
if (typeid (*this) == typeid (B))
cout << "True: Same type as B." << endl;
else
cout << "False: Not the same type as B." << endl;
}
int main () {
A a;
B b;
a.Check (); // should be false
b.Check (); // should be true
return 0;
}
答案 2 :(得分:0)
一种方法是将Check
的定义从类定义中拉出来,以便在编译器到达函数定义时定义B
。
class A {
//...
void Check();
//...
};
class B { /* ... */ };
void A::Check() {
//...
}
答案 3 :(得分:0)
将您的定义移至B类声明下方。
答案 4 :(得分:0)
在声明B之后移动函数体。
#include <iostream>
#include <typeinfo>
struct A
{
int i_;
void Check();
};
struct B : A
{
double d_;
};
void A::Check()
{
using namespace std;
if (typeid (*this) == typeid (B))
{
cout << "True: Same type as B." << endl;
}
else
{
cout << "False: Not the same type as B." << endl;
}
}
int main()
{
A a;
B b;
a.Check(); // should be false
b.Check(); // should be true
return 0;
}
答案 5 :(得分:0)
您好, 即使你把A :: Check的定义放在课外,结果也不会是你所期望的。这是因为B对象转换为方法中的A对象,因此这指向A对象,因此typeid总是不同的。要解决此问题,请将方法声明为虚拟。
但是,我仍然不明白你为什么要进行这样的测试O_o ??正如CAdaker所说,这不是一个好习惯