【问题标题】:Correct use of shared_ptr and make_shared in exercise from Stroustrup's PPP book Chapter 12在 Stroustrup 的 PPP 书籍第 12 章的练习中正确使用 shared_ptr 和 make_shared
【发布时间】:2014-04-20 08:49:36
【问题描述】:

我正在做 Bjarne Stroustrup 的 Programming Principles and Practice Using C++ 第 12 章的练习。

本章中的图形接口库Simple_window.hGraph.h 提供了一个简单的FLTK 包装器。源代码在http://www.stroustrup.com/Programming/Graphics/

要将Shape 附加到Window,用户必须提供对Shape 对象的引用,该对象必须在Window 的生命周期内存在。相关成员函数具有以下签名:

void Graph_lib::Window::attach(Shape& s);

Difference in make_shared and normal shared_ptr in C++ 中引用 cmets 我想利用std::shared_ptrstd::make_shared 来确保分配的Rectangle 对象(派生自Shape)与Simple_window 对象的生命周期相匹配(源自Window)。

第一个解决方案:

#include <iostream>
#include <vector>
#include <memory>
#include <stdexcept>
#include "Simple_window.h"
#include "Graph.h"

/*
Exercise 4 from Chapter 12
Programming Principles and Practice using C++, page 434

Draw a checkers board: 8-by-8 alternating white and red squares.
*/

int main()
{
    using namespace std;
    using namespace Graph_lib;
    using Graph_lib::Rectangle;

    try {
        Simple_window win(Point(20,20),400,300,"Exercise 12.4");
        vector<shared_ptr<Shape>> shapes;

        const auto width = 20;
        const auto height = 20;

        for (auto row = 0; row < 8; row++) {
            for (auto col = 0; col < 8; col++) {
                auto x = col * width;
                auto y = row * height;
                shared_ptr<Rectangle> r(new Rectangle(Point(x,y),width,height));
                shapes.push_back(r);
                if (row % 2 == 0) {
                    r->set_fill_color((col % 2 == 0) ? Color::white : Color::red);
                } else {
                    r->set_fill_color((col % 2 == 1) ? Color::white : Color::red);
                }
                win.attach(*r);
            }
        }
        win.wait_for_button();
    }
    catch(exception &e) {
        cerr << "Exception occured: " << e.what() << endl;
        return 1;
    }
    catch(...) {
        cerr << "Unknown exception occured" << endl;
        return 2;
    }
}

为了使智能指针的使用不那么明确,我使用用户定义的成员函数扩展了Simple_window,该函数在将引用传递给Simple_window::attach(Shape&amp;)之前将智能指针推入向量:

struct Shared_simple_window : Simple_window {
    Shared_simple_window(Point xy, int w, int h, const std::string& title )
        : Simple_window(xy, w, h, title) { }

    void attach(std::shared_ptr<Graph_lib::Shape>&& s)
        { shared_shapes.push_back(s); Simple_window::attach(*s.get()); }

private:
    std::vector<std::shared_ptr<Graph_lib::Shape>> shared_shapes;

};

try 块中的代码现在变成了

Shared_simple_window win(Point(20,20),400,300,"Exercise 12.4");

const auto width = 20;
const auto height = 20;

for (auto row = 0; row < 8; row++) {
    for (auto col = 0; col < 8; col++) {
        auto x = col * width;
        auto y = row * height;
        shared_ptr<Rectangle> r(new Rectangle(Point(x,y),width,height));
        if (row % 2 == 0) {
            r->set_fill_color((col % 2 == 0) ? Color::white : Color::red);
        } else {
            r->set_fill_color((col % 2 == 1) ? Color::white : Color::red);
        }
        win.attach(r);
    }
}
win.wait_for_button();

这行得通,但我的问题是,我怎样才能在这个例子中使用make_shared 而不是new?我尝试用以下内容替换 shared_ptr 声明

auto r = make_shared<Rectangle>(Rectangle(Point(x,y),width,height));

但我收到错误use of deleted function Graph_lib::Rectangle::Rectangle(Graph_lib::Rectangle&amp;&amp;),可能是因为Rectangle 不是为移动而设计的。我应该扩展Rectangle 以使其正常工作吗?

【问题讨论】:

  • auto r = make_shared&lt;Rectangle&gt;(Point(x,y),width,height); 怎么样?
  • @Nick 谢谢,现在我觉得自己很愚蠢,但这是一种很好的方式。我尝试了不同的语法变体,但您提供的最简单的一个结果证明是正确的。你介意张贴作为答案,以便我可以结束这个问题。
  • 此线程中也有类似的 Q 和 A - stackoverflow.com/questions/8789636/…

标签: c++ c++11 shared-ptr


【解决方案1】:

您可以尝试将传递给构造函数的相同参数传递给make_shared,如下所示:

auto r = make_shared<Rectangle>(Point(x,y),width,height);

【讨论】:

  • 我喜欢这个语法而不是我问题中的版本,因为我可以避免输入new,也可以避免输入两次Rectangle
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2014-01-30
  • 1970-01-01
  • 2015-02-22
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多