【问题标题】:c++ double pointer polymorphismc++ 双指针多态
【发布时间】:2015-04-18 03:46:32
【问题描述】:

我正在尝试使用多态性创建一个指针数组。我会让超类的数组指向多个子类。有没有这样做并且仍然使用子类中的方法?这是一个示例代码:

#include <iostream>


class Test1
{
public:
    Test1()
        : x(1)
    {}
    int get_x()
    {
        return x;
    }
private:
    int x;
};

class Test2 : public Test1
{
public:
    Test2()
        : y(2)
    {}
    void print()
    {
        std::cout << get_x() << ' ' << y << std::endl;
    }
private:
    int y;
};

class Test3 : public Test1
{
public:
    Test3()
        : y(3)
    {}
    void print()
    {
        std::cout << get_x() << ' ' << y << std::endl;
    }
private:
    int y;
};

int main()
{
    Test1** test = new Test1*[2];
    for (int i = 0; i < 2; i++)
    {
        if (i % 2 == 0)
        {
            test[i] = NULL;
            test[i] = new Test2;
        }
        else
        {
            test[i] = NULL;
            test[i] = new Test3;
        }
    }

    test[0]->print(); // ERROR. Is this even possible?
    test[1]->print(); // ERROR. Is this even possible?


    return 0;
}

谢谢,我才编码大约 8 个月。

【问题讨论】:

标签: c++ pointers polymorphism


【解决方案1】:

测试[0]->打印(); // 错误。这甚至可能吗?

一般来说,是的。但是,与您的代码无关。

  1. 如果Test1 将成为您的基类并且您将使用new,那么它必须有一个虚拟析构函数(例如,virtual ~Test1() {}
    • 这是delete 在通过指向基类的指针删除派生类型时正常工作所必需的
  2. 您要使用指向基类的指针调用的任何函数都必须存在于基类中(即,您需要 Test1 中的 print 函数)
  3. 如果您希望派生类拥有自己的print 实现,则必须在基类中声明virtual(例如virtual void print();
    • 如果 Test1 实现 print 函数没有意义,那么它可以声明它纯虚拟并且不提供实现(例如,virtual void print() = 0;)从而使它成为一个抽象

【讨论】:

  • 您能更具体地介绍一下虚拟析构函数吗?我在超类中的代码只是虚拟的 ~Test1(){} 并且在子类中我也创建了析构函数吗?
  • 好吧,我想我并不完全理解这一点。虚拟析构器在我的情况下可以工作吗?因为虚拟析构函数不会使类虚拟化,因此我永远无法做到这一点:Test1** test = new Test1*[2];。 (我阅读了您提供的链接,不太了解它应该如何工作)
  • @aglasscage ,您仍然可以使用虚拟析构函数来实例化Test1,并且您必须拥有一个,因为您需要调用delete 在基指针上(用于派生类型)。您不能实例化 abstract 类(即,您不想执行 #3)。
  • 我添加了析构函数并让它工作。非常感谢,我感谢所有的帮助。
【解决方案2】:

如果Test1 有这样一个名为print 的成员函数。您的代码不会按原样编译,因为 Test::print 不存在。因此,至少,您必须定义该成员函数。为了使其真正具有多态性,正如问题的意图所暗示的那样,您应该将Test::print 设为virtual 成员函数,以便将调用该函数的Test2Test3 的实现:

class Test1 { 
    ...
    virtual void print() {
        std::cout << "Test1" << std::endl;
    }
    ...
};

有关更多信息,请参阅this tutorial 了解虚函数。

【讨论】:

  • 谢谢伙计。虚函数成功了。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多