2013 10 15_cpp_lecture_06
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

2013 10 15_cpp_lecture_06

on

  • 2,431 views

 

Statistics

Views

Total Views
2,431
Views on SlideShare
404
Embed Views
2,027

Actions

Likes
0
Downloads
10
Comments
0

3 Embeds 2,027

http://beta.compscicenter.ru 2013
http://compscicenter.ru 13
http://gamma.compscicenter.ru 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

2013 10 15_cpp_lecture_06 Presentation Transcript

  • 1. Лекция 6. Классы Valery Lesin. C++ Basics, 2013 1
  • 2. Типы классов: классы значения • Открытые деструктор, копирующий конструктор; присваивание с семантикой значения • Нет виртуальных функций • Используются как конкретные классы, не как базовые • Чаще размещаются на стеке или являются полем другого класса • Примеры: std::vector<T>, std::complex Valery Lesin. C++ Basics, 2013 2
  • 3. Типы классов: базовые классы • Деструктор: – открытый виртуальный (интерфейс), либо – защищенный невиртуальный (реализация) • Закрытые конструктор копирования и оператор присваивания • Интерфейс определяется виртульными функциями (либо NVI) • Чаще создаются в куче и держатся с помощью умных указателей. Valery Lesin. C++ Basics, 2013 3
  • 4. Типы классов • Классы свойства (traits): – нет состояния, виртуальных функций, – только typedef и статические функции, – обычно не создают объекты этого типа, – пример: std::char_traits<T>. • Классы-стратегии • Классы-исключения Valery Lesin. C++ Basics, 2013 4
  • 5. Определение класса 1. 2. 3. 4. class array { //... }; • Определение класса является объявлением может встречаться в разных единицах трансляции (с учетом ODR). • Можно использовать как struct, так и class. Разница в начальном модификаторе доступа. • Точка с запятой в конце объявления обязательна! Valery Lesin. C++ Basics, 2013 5
  • 6. Функции-члены (member-functions) 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. struct array { double* data_; size_t size_; }; void push_back(array& arr, double value) {delete arr.data_; /*...*/} //////////////////////////////////////////////////////////////// // array.h struct array { void push_back(double value); void resize (size_t new_size); //... }; // array.cpp – compilation optimization void array::push_back(double value) { delete data_; //... } Valery Lesin. C++ Basics, 2013 6
  • 7. Управление доступом 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. struct array { void resize (size_t); void push_back(double); private: void fill_with(double value); private: double* data_; size_t size_; }; • struct – по-умолчанию public, class – private • К private секции имеют доступ только memberфункции или друзья. • Секции могут повторяться в любом порядке. • Начинайте с public секций – интерфейса. Valery Lesin. C++ Basics, 2013 7
  • 8. Определение функций в классе 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. // array.h struct array { void resize (size_t); void push_back(double) { delete data_; //... } //... double* data_; }; inline void array::resize(size_t) { //... } • Для повышения читаемости лучше в объявлении класса оставлять только объявления функций. • Не смешивайте способы объявления – либо все в заголовочном файле, либо в cpp-шнике. Valery Lesin. C++ Basics, 2013 8
  • 9. 4 главные функции • Функции: – Конструктор по умолчанию (без параметров) – Конструктор копирования – Оператор присваивания – Деструктор • Все они создаются автоматически, но могут быть переопределены пользователем. • Если объявлен хоть один конструктор с параметрами, конструктор по умолчанию не создается автоматически. Valery Lesin. C++ Basics, 2013 9
  • 10. Конструкторы 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. struct array { void init(); void init(size_t size, double def = 0.); }; struct array { array(); array(size_t size, double def = 0.); }; void func() { array a; a.init(10, 5.); array arr(10, 5.); array* ptr = new array(10, 5.); } • Конструктор нельзя забыть вызвать или вызвать дважды Valery Lesin. C++ Basics, 2013 10
  • 11. Список инициализации 1. 2. 3. 4. 5. 6. array::array(size_t num, double def) : data_(new double[num]) , size_(num) { fill_with(def); } • Поля класса инициализируются в порядке объявления в классе (т.о. во всех конструкторах в одинаковом порядке) • Поля как объекты создаются до входа в тело конструктора. Valery Lesin. C++ Basics, 2013 11
  • 12. Обязательная инициализация полей 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. struct foobar { foobar(int& value) : pi_ (3.14) , ref_(value) , ofs_("~/some.txt") { name_ = "some"; } private: string int const int& ofstream }; name_; pi_ ; ref_; ofs_; • Обязательны для инициализации: – константы, – ссылки, – объекты без конструктора по умолчанию. Valery Lesin. C++ Basics, 2013 12
  • 13. Деструктор 1. 2. 3. 4. array::~array() { delete data_; } • Освобождает выделенные объектом ресурсы • Вызывается – при выходе локальной переменной из своей области действия – при вызове оператора delete • Деструкторы полей, если они есть, вызываются после тела деструктора • (*) Не должен бросать исключений Valery Lesin. C++ Basics, 2013 13
  • 14. Конструктор копирования Оператор присваивания 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. array::array(array const& other) : data_(new double[other.size_]) , size_(other.size_) { std::copy(data_, data_ + size_, other.data_); } array& array::operator=(array const& other) { if (*other != this) { delete data_; data_ = new double[other.size_]; size_ = other.size_; std::copy(data_, data_ + size_, other.data_); } return *this; } Valery Lesin. C++ Basics, 2013 14
  • 15. Функция swap 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. // swap is a friend function void swap(array& lhs, array& rhs) { using std::swap; swap(lhs.data_, rhs.data_); swap(lhs.size_, rhs.size_); } // or exists member-function array::swap void swap(array& lhs, array& rhs) { lhs.swap(rhs); } • (*) Не должна бросать исключений • Для всех встроенных типов и STL-типов определена std::swap Valery Lesin. C++ Basics, 2013 15
  • 16. swap trick 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. // before: array& array::operator=(array const& other) { if (*other != this) { delete data_; data_ = new double[other.size_]; size_ = other.size_; std::copy(data_, data_ + size_, other.data_); } return *this; } // now: array& array::operator=(array other) { swap(*this, other); return *this; } Valery Lesin. C++ Basics, 2013 16
  • 17. RAII (resource acquisition is initialization) 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. struct out_bin_file // : boost::noncopyable { out_bin_file(const char* name) : file_(fopen(name, "w")){} ~out_bin_file(){ fclose(file_); } private: out_bin_file(out_bin_file const&); out_bin_file& operator=(out_bin_file const&); private: FILE* file_; }; void foo() { // this file will be always closed // before returning from these function out_bin_file file("~/some.txt"); if (...) return; throw std::runtime_error("oops..."); } Valery Lesin. C++ Basics, 2013 17
  • 18. Неудачная инициализация* 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. struct out_bin_file : boost::noncopyable { struct file_failure : std::runtime_error { file_failure(string problem) : std::runtime_error(problem) { } }; out_bin_file(const char* name) : file_(fopen(name, "w")) { if (file_ == nullptr) throw file_failure("cannot open file " + name); } private: FILE* file_; }; Valery Lesin. C++ Basics, 2013 18
  • 19. Преобразование типов • Конструктор от одного параметра задает неявное преобразование типов. Иногда это удобно (std::string), порой – нет. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. struct array { explicit array(size_t num, double def = 0.); //... }; void foo(array const& arr) { /*...*/} void bar() { foo(5); } Valery Lesin. C++ Basics, 2013 19
  • 20. Статические поля 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. struct socket { socket() { if (!lib_init) lib_init = init_socket_lib(); } static bool lib_init; }; //... bool socket::lib_init = false; //////////////////////////////////////// struct singleton { static singleton* create(/*...*/) { static singleton s(/*...*/); return &s; } private: singleton(/*...*/){/*...*/} }; //... auto s = singleton::create(); Valery Lesin. C++ Basics, 2013 20
  • 21. const member-functions 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. struct array { double& at(size_t i) double at(size_t i) const {return data_[i];} {return data_[i];} // this type: array const* const double back() const {return at(size_ - 1);} private: double* data_; size_t size_; }; void foo(array const& x) { double value = x.back(); } Valery Lesin. C++ Basics, 2013 21
  • 22. Логическое постоянство 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. struct matrix { matrix const& inverted () const { return inverted_ ? *inverted_ : (inverted_ = calc_inv()); } //.. mutable matrix* inverted_; }; • Используется чаще всего для различных видов кэша Valery Lesin. C++ Basics, 2013 22
  • 23. Время жизни объектов 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. string* foo(bool cond) { mapped_file file("~/data.bin", read_write); mapped_region reg (file, 0, 0x10000); // .. // what if bad_alloc was fired? string* strs = new string[15]; return new string("text"); } • Локальные объекты удаляются в порядке обратным их созданию • Объекты в динамической памяти удаляются только после вызова delete Valery Lesin. C++ Basics, 2013 23
  • 24. Временные объекты • Если временный объект не инициализирует – именованный объект или – константную ссылку, он удаляется к концу полного выражения. 1. 2. 3. 4. 5. 6. 7. 8. void foo() { string h = "Hello, "; string w = "World!"; const char* str = (h + w).c_str(); // oops! //str is undefined here } Valery Lesin. C++ Basics, 2013 24
  • 25. union 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. struct addr_v4 { uint8_t b1; uint8_t b2; uint8_t b3; uint8_t b4; }; union addr { addr_v4 bytes; uint32_t value; }; void foo() { addr a; a.bytes.b1 = 0x54; } • Все поля расположены по одному адресу • Не может иметь конструкторов/деструкторов Valery Lesin. C++ Basics, 2013 25
  • 26. Вложенные типы 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. struct queue { typedef int T; public: queue(); ~queue(); void push(T); T top () const; void pop (); private: struct node { node* next; T data; }; private: node* head; }; • (*) Вложенные типы становятся друзьями внешнему типу Valery Lesin. C++ Basics, 2013 26
  • 27. Пример array 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. struct array { array(); explicit array(size_t num, double def. = 0); array(array const& other); array& operator=(array const& other); double& at(size_t i); double at(size_t i) const; size_t size () const; bool empty() const; void resize (size_t); void push_back(double); private: void fill_with(double value); private: double* data_; size_t size_; }; Valery Lesin. C++ Basics, 2013 27
  • 28. Рекомендации • Следуйте принципу «Один объект – одна задача» • Лучше маленький класс, чем монолитный – легче понять и проще использовать – монолитные классы часто используют малосвязанные сущности. Но при изменении одной из них, приходится заботится обо всем классе. • Дополнительную функциональность лучше реализовать через внешние функции Valery Lesin. C++ Basics, 2013 28
  • 29. Вопросы? Valery Lesin. C++ Basics, 2013 29