0

C++ 大师。

我正在尝试在 C++ 中实现多态性。我想编写一个带有虚函数的基类,然后在子类中重新定义该函数。然后在我的驱动程序中演示动态绑定。但我就是无法让它工作。

我知道如何在 C# 中做到这一点,所以我想我可能在我的 C++ 代码中使用 C# 的语法时犯了一些语法错误,但这些错误对我来说一点也不明显。因此,如果您能纠正我的错误,我将不胜感激。

#ifndef POLYTEST_H
#define POLYTEST_H
class polyTest
{
 public:
  polyTest();

  virtual void type();

  virtual ~polyTest();
};
#endif

#include "polyTest.h"
#include <iostream>

using namespace std;

void polyTest::type()
{
 cout << "first gen";
}

#ifndef POLYCHILD_H
#define POLYCHILD_H

#include "polyTest.h"

using namespace std;

class polyChild: public polyTest
{
 public:
  void type();
};

#endif

#include "polyChild.h"
#include <iostream>

void polyChild::type() 
{
  cout << "second gen";
}

#include <iostream>
#include "polyChild.h"
#include "polyTest.h"
int main()
{
  polyTest * ptr1;
  polyTest * ptr2;

  ptr1 = new polyTest();
  ptr2 = new polyChild();

  ptr1 -> type();
  ptr2 -> type();
  return 0;
}

我意识到我没有实现构造函数或析构函数,因为这只是一个测试类,它们不需要做任何事情,编译器会提供一个默认的构造函数/析构函数。这就是我收到编译错误的原因吗?为什么会这样?

4

2 回答 2

6

您的指针应该指向基本类型:

polyTest * ptr1;
polyTest * ptr2;

polyChild is-a polyTestpolyTest不是a 。polyChild

于 2013-11-03T21:52:56.553 回答
1

juanchopanza 给了您关于您所问问题的正确答案:您可以将子类型的指针分配给父类型的指针,因为子类也是父类的类型。

派生对象是基类对象(作为其子类),因此可以由基类指针指向。但是基类对象不是派生类对象,因此不能分配给派生类指针。

我会打个比方:狗是动物,猫是动物。你不能说动物总是猫或狗。

在 C++ 中,运行时类型检查是通过 dynamic_cast 实现的,这允许您检查父类是否属于某种类型的子类(在我的类比中,这允许您检查 Animal 是否是 Cat)。编译时向下转换由 static_cast 实现,但此操作不执行类型检查。如果使用不当,可能会产生未定义的行为。

一般来说,向下转换的滥用表明接口设计不佳,除非您正在实现诸如双重调度模式之类的东西,否则您不应该在程序中一直使用向下转换。

另一方面,请大写您的类,这在大多数(如果不是全部)C++ 约定中是相当标准的。我修复了您程序中的所有其他内容,它应该可以编译。

#include <iostream>

using namespace std;

class PolyTest
{
 public:
     virtual ~PolyTest() {} // your example had no body
     virtual void type();

};

void PolyTest::type()
{
 cout << "first gen";
}


class PolyChild: public PolyTest
{
public:
    void PolyChild::type();
};

void PolyChild::type()
{ 
    cout << "second gen"; 
}


int main()
{
    PolyTest* ptr1 = new PolyTest();
    PolyTest* ptr2 = new PolyChild();

    ptr1->type();
    ptr2->type();

    cout << std::endl;

    PolyChild* pChild1 = dynamic_cast<PolyChild*>(ptr1);
    if (pChild1)
        cout << "ptr1 is a PolyChild" << std::endl;
    else
        cout << "ptr1 is NOT a PolyChild" << std::endl;

    PolyChild* pChild2 = dynamic_cast<PolyChild*>(ptr2);
    if (pChild2)
        cout << "ptr2 is a PolyChild" << std::endl;
    else
        cout << "ptr2 is NOT a PolyChild" << std::endl;

    cin.ignore(1);
    return 0;
}

我还添加了一些代码来演示 dynamic_cast<>。同样,您不应该滥用它作为滥用它,这意味着您没有正确设计您的界面。

于 2013-11-03T22:13:30.990 回答