Библиотека сайта 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. Сигналы.
