Библиотека сайта rus-linux.net
Программирование с использованием gtkmm 3. Умный указатель RefPtr
Оригинал: Programming with gtkmm 3Авторы: Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Ole Laursen, Marko Anastasov, Daniel Elstner, Chris Vine, David King, Pedro Ferreira, Kjell Ahlstedt
Дата публикации: 15 Октября 2013 г.
Перевод: А.Панин
Дата перевода: 25 Апреля 2014 г.
Приложение A. Умный указатель RefPtr
Умный указатель для работы с объектами gtkmm реализован в рамках класса Glib::RefPtr
. Если говорить точнее, этот указатель является умным указателем с подсчетом ссылок. Вы должны быть знакомы с такими классами, как std::auto_ptr<>
, std::unique_ptr<>
и std::shared_ptr<>
, которые также реализуют умные указатели. Класс Glib::RefPtr<>
похож на класс std::shared_ptr<>
, в рамках которого также осуществляется подсчет ссылок. Класс Glib::RefPtr<>
был представлен задолго до появления в стандартной библиотеке языка программирования C++ класса умного указателя с подсчетом ссылок.
Умный указатель ведет себя практически так же, как и обычный указатель. Ниже приведено несколько примеров его использования.
A.1. Копирование
Glib::RefPtr<Gdk::Pixbuf> refPixbuf = Gdk::Pixbuf::create_from_file(filename); Glib::RefPtr<Gdk::Pixbuf> refPixbuf2 = refPixbuf;
std::vector
и std::list
.
std::list< Glib::RefPtr<Gdk::Pixbuf> > listPixbufs; Glib::RefPtr<Gdk::Pixbuf> refPixbuf = Gdk::Pixbuf::create_from_file(filename); listPixbufs.push_back(refPixbuf);
A.2. Разыменование
->
для вызова методов расположенного уровнем ниже экземпляра класса точно так же, как это делается при работе с обычным указателем.
Glib::RefPtr<Gdk::Pixbuf> refPixbuf = Gdk::Pixbuf::create_from_file(filename); int width = refPixbuf->get_width();
*
для доступа к расположенному уровнем ниже экземпляру класса.
Glib::RefPtr<Gdk::Pixbuf> refPixbuf = Gdk::Pixbuf::create_from_file(filename); Gdk::Pixbuf& underlying = *refPixbuf; //Ошибка синтаксиса - компиляция будет прервана.
A.3. Преобразование
Glib::RefPtr<Gtk::TreeStore> refStore = Gtk::TreeStore::create(columns); Glib::RefPtr<Gtk::TreeModel> refModel = refStore;
Это означает, что любой метод, принимающий аргумент базового типа const Glib::RefPtr<BaseType>
также может принимать аргумент унаследованного от базового типа const Glib::RefPtr<DerivedType>
. В данном случае будет осуществлено точно такое же неявное преобразование типов, как и при работе с обычным указателем.
Glib::RefPtr<Gtk::TreeStore> refStore = Glib::RefPtr<Gtk::TreeStore>::cast_dynamic(refModel); Glib::RefPtr<Gtk::TreeStore> refStore2 = Glib::RefPtr<Gtk::TreeStore>::cast_static(refModel);
A.4. Проверка на нулевое значение
Glib::RefPtr<Gtk::TreeModel> refModel = m_TreeView.get_model(); if(refModel) { int cols_count = refModel->get_n_columns(); ... }
Но, в отличие от обычных указателей, умные указатели автоматически инициализируются с использованием нулевого значения, поэтому вам не придется помнить о необходимости самостоятельного выполнения инициализации.
A.5. Постоянство значений
Методика использования ключевого слова const
в языке программирования C++ не достаточно очевидна. Вы можете не осознавать того, что объявление const Something*
позволяет описать указатель на неизменный объект const Something
. При этом может изменяться указатель, но не объект Something
, на который он указывает.
Исходя из этого, в случае работы с умным указателем эквивалентом записи Something*
для параметра метода является запись const Glib::RefPtr<Something>&
, а эквивалентом записи const Something*
является запись const Glib::RefPtr<const Something>&
.
Запись const ... &
используется в обоих случаях для повышения производительности операции аналогично тому, как для передачи строки в качестве параметра метода с целью исключения излишних операций копирования используется запись std::string&
вместо записи std::string
.
Следующий раздел : Приложение B. Сигналы.