【问题标题】:How can I sum of all element in vector?如何对向量中的所有元素求和?
【发布时间】:2021-08-21 04:45:02
【问题描述】:

我想输入形状的数量和形状的面积之和。

第一行输入要计算的形状数量,第一行之后可以输入形状的类型,形状的大小。

但是我在计算三角形和矩形的面积时遇到了问题,除了圆形。只有圆的面积计算得很好..

$ ./a.out
1
R 2.0 1.0
0.00

$ ./a.out
1
T 2.0
0.00

$ ./a.out
1
C 1.0
3.14

我认为问题来自

 for (int i = 0; i < n ; i++)
    {
        sum += collection[i]->area(collection);
    }

这段代码!我认为我的面积函数只计算向量的第一个元素.....

#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;

class Shape{
protected:
    int _r;
    int _w;
    int _h;

public:
    Shape(double r) : _r(r) {}
    Shape(double w, double h) : _w(w), _h(h) {}
    virtual double area(vector<Shape *>) = 0;
};

class Circle : public Shape{
public:
    Circle(double r) : Shape(r) {}
    double area(vector<Shape *>) { return _r*_r*atan(1)*4.0; }
};

class Triangle : public Shape{
public:
    Triangle(double s) : Shape(s) {}
    double area(vector<Shape *>) { return sqrt(3) * pow(_r, 2) / 4; }
};

class Rectangle : public Shape{
public:
    Rectangle(double w, double h) :Shape(w, h) {}
    double area(vector<Shape *>) { return  _w * _h ;}
};

int main()
{

    int n;
    char info;
    int value;
    int value2;
    double sum;
    vector<Shape*> collection;
    vector<int> answer;

    sum = 0;

    cin >> n;

    for(int i = 0 ; i < n + 1; i++)
    {
        cin >> info;
        if (info == 'C')
        {
            cin >> value;
            Circle c(value);
            collection.push_back(&c);
        }
        else if (info == 'R')
        {
            cin >> value;
            cin >> value2;
            Rectangle r(value, value2);
            collection.push_back(&r);
        }
        else
        {
            cin >> value;
            Triangle t(value);
            collection.push_back(&t);
        }
    }
    for (int i = 0; i < n + 1 ; i++)
    {
        sum += collection[i] -> area(collection);
    }
    cout << fixed << setprecision(2) << sum << endl;
}

【问题讨论】:

  • 您的代码doesn't compile。你不能推回area,因为它不是Shape*的函数。
  • 尝试推送Shape 的副本而不是指针。因为在push_back 之后您的所有输入都超出了范围。
  • 您创建形状,将其地址推入向量中,当您到达范围的末尾时,您的对象被销毁,但地址在向量中保持不变,指向垃圾。这就是所谓的悬空指针。
  • @LouisGo: Shape 是纯虚拟的,因此std::vector&lt;Shape&gt; 无效。
  • 已经有 std::accumulate 用于此目的

标签: c++ class vector


【解决方案1】:

有很多有趣的错误:

  1. 我不知道您为什么要将 vector&lt;Shape *&gt; 传递给 area() 方法。
  2. 我不明白你为什么从0 .. n+1 迭代。它与您提供的输入不匹配。
  3. 如 cmets 中所述,您将继续引用指向已超出范围的对象的指针。使用堆是解决此问题的简单方法。使用unique_ptr 还可以确保清理内存。
  4. 由于您使用的是继承,因此最好让基类具有虚拟析构函数。
#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
#include <memory>

using namespace std;

class Shape{
  protected:
    int _r;
    int _w;
    int _h;

  public:
    Shape(double r) : _r(r) {}
    Shape(double w, double h) : _w(w), _h(h) {}
    virtual ~Shape() = default;
    virtual double area() = 0;
};

class Circle : public Shape{
  public:
    Circle(double r) : Shape(r) {}
    double area() { return _r*_r*atan(1)*4.0; }
};

class Triangle : public Shape{
  public:
    Triangle(double s) : Shape(s) {}
    double area() { return sqrt(3) * pow(_r, 2) / 4; }
};

class Rectangle : public Shape{
  public:
    Rectangle(double w, double h) :Shape(w, h) {}
    double area() { return  _w * _h ;}
};

int main() {
    int n;
    char info;
    int value;
    int value2;
    double sum = 0
    vector<std::unique_ptr<Shape>> collection;

    cin >> n;

    for(int i = 0 ; i < n; i++)
    {
        cin >> info;
        if (info == 'C')
        {
            cin >> value;
            collection.push_back(std::make_unique<Circle>(value));
        }
        else if (info == 'R')
        {
            cin >> value;
            cin >> value2;
            collection.push_back(std::make_unique<Rectangle>(value, value2));
        }
        else
        {
            cin >> value;
            collection.push_back(std::make_unique<Triangle>(value));
        }
    }
    for (int i = 0; i < n; i++)
    {
        sum += collection[i]->area();
    }
    cout << fixed << setprecision(2) << sum << endl;
}

【讨论】:

  • 1 。我不知道你为什么将 vector 传递给 area() 方法。 -> 因为我想创建计算所有面积总和的参数为 vector 的方法。
  • 2.我不明白你为什么从 0 .. n+1 迭代。它与您提供的输入不匹配。 -> 我想是的。但实际上,我的第一行输入需要 n+1。例如,如果我在第一行输入 2,我的程序只考虑一个形状,而不是两个形状数
  • 3. 如 cmets 中所述,您将继续引用指向已超出范围的对象的指针。使用堆是解决此问题的简单方法。使用 unique_ptr 还可以确保清理内存。 -> 我想使用,但是我的编译器显示错误。你的编译器在这根绳子上表现好吗??
猜你喜欢
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-24
  • 2021-08-09
  • 1970-01-01
  • 2016-08-02
相关资源
最近更新 更多