2014-04-20 31 views
3

我正在從Bjarne Stroustrup的編程原理和實踐中使用C++的第12章開始練習。從Stroustrup的PPP書籍練習中正確使用shared_ptr和make_shared第12章

本章中的圖形界面庫Simple_window.hGraph.h提供了一個圍繞FLTK的簡單包裝。源代碼可以在http://www.stroustrup.com/Programming/Graphics/

要附加ShapeWindow,用戶必須提供一個Shape對象,它必須存在Window的壽命的參考。有關成員函數具有以下特徵:

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

引用在Difference in make_shared and normal shared_ptr in C++的意見,我想利用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; 
    } 
} 

爲了使使用智能指針少明確的I與推動智能指針到載體傳遞的引用一起Simple_window::attach(Shape&)前一個用戶定義成員函數擴展Simple_window的:

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?我試着用以下

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

更換shared_ptr聲明,但是我得到一個錯誤use of deleted function Graph_lib::Rectangle::Rectangle(Graph_lib::Rectangle&&),可能是因爲Rectangle的目的不是要被移動。我應該延長Rectangle才能使用嗎?

+2

怎麼樣'汽車R = make_shared (點(X,Y),寬度,高度);'代替? – imreal

+1

@Nick謝謝,現在我覺得很愚蠢,但是很好。我嘗試了不同的語法變體,但您提供的最簡單的變體是正確的。你介意張貼作爲答案,所以我可以關閉這個問題。 – Brandin

+0

類似的Q和A也在這個線程 - http://stackoverflow.com/questions/8789636/errors-in-stdmake-shared-when-trying-to-make-shared-ptr – Brandin

回答

3

您可以嘗試通過將傳遞給構造相同的參數make_shared這樣的:

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

我喜歡這個語法在版本中我的問題是因爲我可以避免輸入'new'並且也避免輸入'Rectangle'兩次 – Brandin

相關問題