【问题标题】:A list of derived classes of a virtual base class虚拟基类的派生类列表
【发布时间】:2019-11-04 21:37:52
【问题描述】:

我尝试创建一个包含 2 个方法的基本虚拟类“Shape”。下面我创建了 3 个从基类继承的子类。在主函数中,我创建了 3 个实例,每个子类一个,并且我希望有一个从我的基类创建的所有子类的列表,该列表应该可以通过基类中定义的任一虚拟方法进行排序。

我尝试根据互联网上的一些示例来实现列表库,但我对它的理解不够好,无法使其工作。

#include <iostream>
#include <cmath>
#include <conio.h>
#include <list>

using namespace std;

class Shape
{
protected:
int value_;

public:
   /*static list<Shape*> instances_;
   Shape(int val);
   static void showList();*/
   virtual void surface()=0;
   virtual void circuit()=0;

};

/*Shape::Shape(int val) {
   instances_.push_back(this);
   value_ = val;}

list<Shape*> Shape::instances_;

void Shape::showList() {
   for (list<Shape*>::iterator p = instances_.begin();
        p != instances_.end(); ++p)
      cout << (*p)->value_ << endl;}*/
//////////////////////////////////

class Circle :public Shape
{
   float r;
public:
   Circle(float x)
   {
      r=x;
   }
   virtual void surface()
   {
      cout<<"Circle surface: "<<3.14*r*r<<endl;
   }
   virtual void circuit(){
      cout<<"Circle circuit: "<<3.14*2*r<<endl;
   }
};
////////////////////////////////////////

class Square:public Shape
{
   float a;
public:
   Square:public (float x)
   {
      a=x;
   }
   virtual void surface()
   {
      cout<<"Square surface: "<<a*a<<endl;
   }
    virtual void circuit(){
      cout<<"Square circuit : "<<4*a<<endl;
   }
};

int main()
{
    Circle k(8);
    Square kw(2);


   return 0;
};

【问题讨论】:

  • 其中一半被注释掉了。将其转换为显示您的问题的最小示例。
  • 除了您绝对应该阅读有关虚拟析构函数和“覆盖”关键字的事实之外,您究竟想要实现什么?类列表?这是什么意思?
  • 您想要类列表还是实例列表?你想达到什么目的?这一切都非常不清楚。作为一般建议,请使用tour 并阅读How to Ask
  • 我想要一个包含任何子类(圆形、方形)的所有实例的可排序列表。我注释掉了我使用 lst 库使其工作的尝试。
  • 请展示您的尝试。你有一个std::vector&lt;Shape*&gt;

标签: c++ class inheritance vectorization subclass


【解决方案1】:

这段代码中有几处可以改进。但是,您必须了解继承、多态的概念以及在 C++ 中实现多态背后的粗略细节。

例如:默认的基类析构函数不是自动虚拟的。当您打算实现多态结构时,您需要指定一个虚拟基类析构函数。派生类自动设置为虚拟当且仅当基类具有虚拟析构函数。

要对形状列表进行排序,您首先需要创建一个Shape* 列表。然后你需要编写一个比较函数,它将采用 2 个形状并使用它们的一个成员来比较它们。在您的示例中,没有什么可使用的。两个成员函数都是void,成员变量都是私有的。

查看下面的代码,希望它会有意义。

#include <iostream>
#include <cmath>
#include <list>

struct Shape
{
    Shape() = default;

    virtual float surface() const = 0;
    virtual void circuit() = 0;

    virtual ~Shape() noexcept = default;
};

class Circle final : public Shape
{
    private:
        float r;

    public:
        Circle(float r_) : r(r_)
        {;}

        float surface() const override
        {
            return M_PI*pow(r,2);
        }

        void circuit() override
        {
            std::cout<<"Circle circuit: " << 2.f*M_PI*r <<std::endl;
        }

        ~Circle() noexcept = default;
};

class Square final : public Shape
{
    private:
        float a;

    public:
        Square(float a_) : a(a_)
        {;}

        float surface() const override
        {
            return pow(a,2);
        }

        void circuit() override
        {
            std::cout<<"Square circuit: " << 4.f*a <<std::endl;
        }

        ~Square() noexcept = default;
};


bool compare_shape(const Shape *const s1, const Shape *const s2)
{
    return (s1->surface() < s2->surface());
}

int main()
{
    // no polymorphism
    Circle c(8);
    std::cout<< "Circle surface: " << c.surface() <<std::endl;
    c.circuit();

    Square s(2);
    std::cout<< "Square surface: " << s.surface() <<std::endl;
    s.circuit();

    std::cout<< "____________________" <<std::endl<<std::endl;

    // polymorphism
    Shape *c_ptr = new Circle(8);
    std::cout<< "Circle surface: " << c_ptr->surface() <<std::endl;
    c_ptr->circuit();
    delete c_ptr;

    Shape *s_ptr = new Square(2);
    std::cout<< "Square surface: " << s_ptr->surface() <<std::endl;
    s_ptr->circuit();
    delete s_ptr;

    std::cout<< "____________________" <<std::endl<<std::endl;

    // list of Shapes
    std::list<Shape*> shapes;
    shapes.push_back( new Circle(8) );
    shapes.push_back( new Square(2) );

    for (auto &&i : shapes)
    {
        std::cout<< "Shapes' surface: " << i->surface() <<std::endl;
        i->circuit();
    }

    std::cout<< "\n-- sorting the list based on the shapes' surface.\n" <<std::endl;
    shapes.sort(compare_shape);

    for (auto &&i : shapes)
    {
        std::cout<< "Shapes' surface: " << i->surface() <<std::endl;
        i->circuit();
    }
};

在线代码示例:https://rextester.com/EBKIH52610

【讨论】:

    【解决方案2】:

    如果您想以多态方式进行排序,请搜索有关重载 `bool operator

    【讨论】:

      猜你喜欢
      • 2020-09-30
      • 2023-03-23
      • 2016-08-13
      • 2015-10-24
      • 2018-12-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      • 2013-09-02
      相关资源
      最近更新 更多