我正在從Bjarne Stroustrup的編程原理和實踐中使用C++的第12章開始練習。從Stroustrup的PPP書籍練習中正確使用shared_ptr和make_shared第12章
本章中的圖形界面庫Simple_window.h
和Graph.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++的意見,我想利用std::shared_ptr
和std::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
才能使用嗎?
怎麼樣'汽車R = make_shared(點(X,Y),寬度,高度);'代替? –
imreal
@Nick謝謝,現在我覺得很愚蠢,但是很好。我嘗試了不同的語法變體,但您提供的最簡單的變體是正確的。你介意張貼作爲答案,所以我可以關閉這個問題。 – Brandin
類似的Q和A也在這個線程 - http://stackoverflow.com/questions/8789636/errors-in-stdmake-shared-when-trying-to-make-shared-ptr – Brandin