前向声明和typeid

时间:2009-12-16 16:16:26

标签: c++ gcc declaration forward-declaration typeid

我想根据子类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’

我怎么能解决这个问题?

6 个答案:

答案 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所说,这不是一个好习惯