【问题标题】:How to make polymorphic field of class in C++? How to use polymorphism correctly in this case?如何在 C++ 中创建类的多态字段?在这种情况下如何正确使用多态性?
【发布时间】:2019-11-26 18:52:18
【问题描述】:

我有课

class A 
{
    BasePtr * ptr;
    virtual BasePtr * getPtr() { return ptr; }
    virtual void pure() = 0;
}

我想从中派生两个类来创建自己的 ptr 版本:

class B : public A 
{
    B() : A() { ptr = new RoundPtr(); }
};

class C : public A 
{
    C() : A() { ptr = new SquarePtr(); }
}

然后我创建一个指向基本类的指针列表:

A * list[2];
list[0] = new B();
list[1] = new C();

并调用此方法:

list[i]->getPtr();

但我发现它返回一个未初始化的指针。

那么,这里如何正确使用多态呢?如何正确创建此字段以使用不同类型的字段?

【问题讨论】:

  • 这段代码不能编译,但如果错误以明显的方式得到修复,那么指针就会被初始化。请贴出真实代码。
  • 我们可以得到minimal reproducible example 吗?就像代码不会编译一样。
  • Works fine for me 一旦语法错误等被修复。
  • 添加编译代码作为答案

标签: c++ inheritance polymorphism abstract-class virtual-functions


【解决方案1】:

好的,我测试了这段代码,它工作得很好 o_0 但是当我尝试调用多态对象指针的方法时,我在更复杂的程序中崩溃了。也许我的项目中还有其他错误。

答案是:

#include <iostream>

class Ptr {
    public:
        Ptr(int x, int y) : centerX(x), centerY(y) {}
        virtual ~Ptr() {}
        virtual void foo() = 0;

    protected:
        int centerX, centerY;
};

class RoundPtr: public Ptr {
    public:
        RoundPtr(int x, int y, int radius) : Ptr(x, y), circleRadius(radius) {}
        virtual void foo() { std::cout << "RoundPtr, x: " << centerX << ", y: " << centerY << ", radius: " << circleRadius << std::endl; }

    protected:
        int circleRadius;
};

class SquarePtr: public Ptr {
    public:
        SquarePtr(int x, int y, int w, int h) : Ptr(x, y),
            leftX(centerX - w/2), leftY(centerY - h/2),
            width(w), height(h)
            {}

        virtual void foo() { std::cout << "SquarePtr, x: " << centerX << ", y: " << centerY << ", leftX: " << leftX << ", leftY: " << leftY << ", width: " << width << ", height: " << height << std::endl; }

    protected:
        int leftX, leftY;
        int width, height;
};

class A {
    protected:
        Ptr * ptr;

    public:
        A() : ptr(nullptr) {}
        virtual ~A() {}

        virtual Ptr * getPtr() { return ptr; }
};

class B : public A {
    public:
        B() : A() { ptr = new RoundPtr(0, 0, 10); }
        virtual ~B() { delete ptr; }
};

class C : public A {
    public:
        C() : A() { ptr = new SquarePtr(5, 5, 10, 10); }
        virtual ~C() { delete ptr; };
};

int main()
{
  A * bObj = new B();
  A * cObj = new C();

  bObj->getPtr()->foo();
  cObj->getPtr()->foo();

  delete bObj;
  delete cObj;
}

任何人都可以检查此代码吗?你觉得它有什么问题吗?是很好的解决方案吗?是否可以在这里使用来自 c++11 的智能指针?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 2020-08-06
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多