【问题标题】:Using unique_ptr with vector将 unique_ptr 与向量一起使用
【发布时间】:2016-10-01 17:23:43
【问题描述】:

我正在尝试将shared_ptr 使用的书面代码转换为unique_ptr,因为在其使用代码中似乎shared_ptr 是不必要的,这将是一个智能指针的练习。据我可以用调试器检测到问题出在v.at(i)->push_back(t); 上。因此,只要输入一个值,程序就会崩溃。

shared_ptr 的工作代码:

#include <iostream>
#include <iomanip>
#include <memory> // For smart pointers
#include <vector> // For vector container
#include <locale> // For toupper()
using std::vector;
using std::shared_ptr;
int main()
{
    vector <shared_ptr<vector<double>>>records; // Temperature records by days
    size_t day{ 1 }; // Day number
    char answer{}; // Response to prompt
    double t{}; // A temperature
    while (true) // Collect temperatures by day
    { // Vector to store current day's temperatures created on the heap
        auto pDay = std::make_shared<vector<double>>();
        records.push_back(pDay); // Save pointer in records vector
        std::cout << "Enter the temperatures for day " << day++
            << " separated by spaces. Enter 1000 to end:\n";
        while (true)
        { // Get temperatures for current day
            std::cin >> t;
            if (t == 1000.0) break;
            pDay->push_back(t);
        }
        std::cout << "Enter another day's temperatures (Y or N)? ";
        std::cin >> answer;
        if (toupper(answer) == 'N') break;
    }
    double total{};
    size_t count{};
    day = 1;
    std::cout << std::fixed << std::setprecision(2) << std::endl;
    for (auto record : records)
    {
        std::cout << "\nTemperatures for day " << day++ << ":\n";
        for (auto temp : *record)
        {
            total += temp;
            std::cout << std::setw(6) << temp;
            if (++count % 5 == 0) std::cout << std::endl;
        }
        std::cout << "\nAverage temperature: " << total / count << std::endl;
        total = 0.0;
        count = 0;
    }
}

输出:

23 34 29 36 1000
Enter another day's temperatures (Y or N)? y
Enter the temperatures for day 2 separated by spaces. Enter 1000 to end:
34 35 45 43 44 40 37 35 1000
Enter another day's temperatures (Y or N)? y
Enter the temperatures for day 3 separated by spaces. Enter 1000 to end:
44 56 57 45 44 32 28 1000
Enter another day's temperatures (Y or N)? n

Temperatures for day 1:
23.00 34.00 29.00 36.00
Average temperature: 30.50

Temperatures for day 2:
34.00 35.00 45.00 43.00 44.00
40.00 37.00 35.00
Average temperature: 39.13

Temperatures for day 3:
44.00 56.00 57.00 45.00 44.00
32.00 28.00
Average temperature: 43.71

转换后的代码带有unique_ptr:

#include <iostream>
#include <vector>
#include <memory>
#include <iomanip>

using std::vector;


int main()
{ // Function scope starts here

    // a vector(outside) holding unique_ptrs to a vector(inside) which type is double
    vector<std::unique_ptr<vector<double>>> v;
    size_t day{ 1 };
    char answer{};
    double t{};


    while (true)
    {
        size_t i{};
        auto pDay = std::unique_ptr<vector<double>>();
        v.push_back(std::move(pDay));

        std::cout << "Enter the temperatures for day " << day++
            << " separated by spaces. Enter 1000 to end:\n";

        while (true)
        {
            std::cin >> t;
            if (t >= 1000.0) break;
            v.at(i)->push_back(t);
            ++i;
        }

        //std::cout << v.at(0)->at(0) << std::endl;
        std::cout << "Enter another day's temperatures (Y or N)? ";
        std::cin >> answer;
        if (toupper(answer) == 'N') break;
    }

    double total{};
    size_t count{};
    day = 1;
    std::cout << std::fixed << std::setprecision(2) << std::endl;

    for (auto const& record : v)
    {
        std::cout << "\nTemperatures for day " << day++ << ":\n";
        for (auto temp : *record)
        {
            total += temp;
            std::cout << std::setw(6) << temp;
            if (++count % 5 == 0) std::cout << std::endl;
        }
        std::cout << "\nAverage temperature: " << total / count << std::endl;
        total = 0.0;
        count = 0;
    }

} // Function scope ends here

【问题讨论】:

  • 请提供minimal reproducible example,不要包含文字图片!当您尝试减少问题空间时,问题对您来说应该会变得更加明显。
  • 这不是最小的。
  • A unique_ptr> 是一种反模式。 (嵌套向量也一样)
  • @DieterLücking - 为什么嵌套向量是反模式? (总的来说,正如我想你所说的那样,不是这个问题。)
  • @davidbak,反模式是用std::unique_ptr 替换std::vector,因为向量可以移动(与移动unique_ptr 的效率相同)并且可以动态调整大小(不需要需要时手动分配)。嵌套向量可以使用std::vector&lt;std::vector&lt;T&gt;&gt; 完成,它更简单易用,与std::vector&lt;std::unique_ptr&lt;std::vector&lt;T&gt;&gt;&gt; 相比没有任何真正的缺点。

标签: c++ c++11 smart-pointers


【解决方案1】:

你的std::unique_ptr&lt;std::vector&lt;double&gt;&gt; 没有指向任何东西。您需要使用指向向量的指针对其进行初始化。

【讨论】:

  • @snr:您创建了std::shared_ptr&lt;std::vector&lt;double&gt;&gt; 使用std::make_shared&lt;std::vector&lt;double&gt;&gt;。这分配了控制记录和一个对象。如果你只是默认构造了一个共享指针,它也会失败。
  • @snr 见 std::make_unique(等同于 std::make_shared)
  • @snr:你说它是“工作代码”。你在撒谎吗?
  • 该解决方案与 c++14 兼容。 @DieterLücking
  • 如何在c++11中初始化? @DietmarKühl
猜你喜欢
  • 2012-12-07
  • 1970-01-01
  • 2017-05-22
  • 2020-05-20
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多