2

我想根据子类的类型检查超类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’

我该如何解决这个问题?

4

6 回答 6

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 中定义并由虚拟方法调用处理。

于 2009-12-16T16:23:24.293 回答
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;
}
于 2009-12-16T16:20:50.487 回答
0

嗨,即使您将 A::Check 的定义放在类之外,结果也不会是您所期望的。这是因为 B 对象 this 在方法中转换为 A 对象,所以 this 指向 A 对象,因此 typeid 总是不同的。为了解决这个问题,声明方法 virtual。

但是,我仍然不明白您为什么要执行这样的测试 O_o ?正如CAdaker所说,这不是一个好习惯

于 2009-12-16T16:59:17.293 回答
0

一种方法是Check从类定义中提取定义,以便B在编译器到达函数定义时定义。

class A {
    //...
    void Check();
    //...
};
class B { /* ... */ };

void A::Check() {
    //...
}
于 2009-12-16T16:20:28.350 回答
0

将您对 Check 的定义移到您的 B 类声明下方。

于 2009-12-16T16:21:39.647 回答
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;
}
于 2009-12-16T16:22:07.350 回答