Форум программистов, компьютерный форум CyberForum.ru

Собеседования по С++ для джуна - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Необязательные временные объекты http://www.cyberforum.ru/cpp-beginners/thread1506633.html
Помогите с задачкой: Класс Car содержит модель автомобиля. Функция Find определяет, присутствует ли указанная модель в списке автомобилей. class Car { string model_; public: Car(string mod) :model_(mod){} bool operator==(const Car& other) {
C++ Уведомления между потоками Здравствуйте! Набросал код для экспериментов: #include "stdafx.h" int блок_1(HWND *hWnd, MyStruct* strukt_1); int сервис_1(HWND *hWnd, MyStruct* strukt_1); void блок(HWND *hWnd, MyStruct* strukt_1)//запускаем основной поток { int q = 0; http://www.cyberforum.ru/cpp-beginners/thread1506588.html
C++ Когда в ОС используется COM ?
Для каких действий ОС использует COM технологию ? Всегда ли она используется при исполнении exe файлов?
C++ Где найти все глаголы для ShellExecute ?
Здравствуйте. Где и как посмотреть список допустимых глаголов системы? Знаю о существовании страницы в msdn , но функция которую я нашел в интернете и использую использует глагол "runas", которого нет на странице.
C++ Write some short C or C++ code to generate a segmentation fault http://www.cyberforum.ru/cpp-beginners/thread1506555.html
Write some short C or C++ code to generate a segmentation fault
C++ Write some short C or C++ code to generate a stack overflow Write some short C or C++ code to generate a stack overflow подробнее

Показать сообщение отдельно
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
04.08.2015, 13:15     Собеседования по С++ для джуна
Цитата Сообщение от Ilot Посмотреть сообщение
А это уже вопрос формализма. Тут никто не может быть правым или ошибаться.
Это прописано в стандарте.

Вот еще:

1.8 [intro.object]/6 Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects that are not bit-fields may have the same address if one is a subobject of the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they shall have distinct addresses. [...]

Отсюда следует, что согласно формальной терминологии С++, объекты могут иметь нулевой размер.

Добавлено через 21 час 26 минут
Кстати мы тут говорили-говорили про empty base class optimization, но так и не сказали, где эта оптимизация применяется. Попробую немного устранить этот пробел (на примере libstd++).

Давайте рассмотрим самый обычный std::unique_ptr, которым мы все так любим пользоваться. Вот его объявление:
C++
1
2
3
4
template<
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;
То есть класс Deleter, через который выполняется освобождение ресурса, является частью типа и присутствует в любом случае. Если мы его не указываем сами, то это будет std::default_delete<T>, который делает просто delete.
Сам объект deleter мы можем передать непосредственно в конструктор, например такой:
C++
1
unique_ptr( pointer p, Deleter d1 );
Какой отсюда пока можно сделать вывод? Вывод такой - объект, который используется для удаления ресурса, хранится в классе unique_ptr в виде скажем Deleter d. И в принципе не важно, это наш объект, который мы передали в конструктор, или умолчательный.
Смотрим дальше. Вот есть код:
C++
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
#include <iostream>
#include <memory>
 
struct Foo { int x; };
 
// пишем специализацию, потому что make_unique работает только с дефолтным делитером
// можно было написать свой класс и передавать в конструктор, указанный выше
namespace std
{
template<>
struct default_delete<Foo> {
    void operator()(Foo * ptr)
    {
        std::cout << "D is deleting a Foo\n";
        delete ptr;
    }
};
}
 
int main()
{
    auto p = std::make_unique<Foo>();
    std::cout << sizeof(p) << '\n';
    std::cout << sizeof(void*) << '\n';
}
Вывод - 8 8. Это значит, что размер указателя и unique_ptr одинаковы! Как так? Ведь мы же выяснили, что unique_ptr должен хранить внутри себя объект делитера, а это минимум 1 байт + выравнивание. Лезем в код unique_ptr и видим:
C++
1
2
typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
 __tuple_type                                      _M_t;
То есть на самом деле unique_ptr хранит внутри себя указатель и делитер не как отдельные поля, а как std::tuple. Казалось бы, нафига? Лезем в код std::tuple и видим:
C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
template<std::size_t _Idx, typename _Head, bool _IsEmpty>
  struct _Head_base;
 
template<std::size_t _Idx, typename _Head>
  struct _Head_base<_Idx, _Head, true>
  : public _Head
  {
    constexpr _Head_base()
    : _Head() { }
 
    constexpr _Head_base(const _Head& __h)
    : _Head(__h) { }
 
    template<typename _UHead>
      _Head_base(_UHead&& __h)
  : _Head(std::forward<_UHead>(__h)) { }
 
    _Head&       _M_head()       { return *this; }
    const _Head& _M_head() const { return *this; }
  
    void 
    _M_swap_impl(_Head& __h)
    {
  using std::swap;
  swap(__h, _M_head());
    }
  };
 
template<std::size_t _Idx, typename _Head>
  struct _Head_base<_Idx, _Head, false>
  {
    constexpr _Head_base()
    : _M_head_impl() { }
 
    constexpr _Head_base(const _Head& __h)
    : _M_head_impl(__h) { }
 
    template<typename _UHead>
      _Head_base(_UHead&& __h)
  : _M_head_impl(std::forward<_UHead>(__h)) { }
 
    _Head&       _M_head()       { return _M_head_impl; }
    const _Head& _M_head() const { return _M_head_impl; }        
 
    void
    _M_swap_impl(_Head& __h)
    { 
  using std::swap;
  swap(__h, _M_head());
    }
 
    _Head _M_head_impl; 
  };
Мы видим специализацию шаблона! Одна - для пустого класса, тогда мы наследуемся и у нас есть empty base class optimization! И одна - если класс не пустой, тогда у нас появляется поле _Head _M_head_impl;
То есть: в данной реализации tuple у нас есть оптимизация пустых классов! Поэтому unique_ptr и использует tuple: мы автоматом получаем, что если класс делитера у нас пустой, то он не занимает у нас никакого места! Поэтому в данном случае размеры unique_ptr и обычного указателя совпадают.

Еще оптимизация пустого базового класса применяется например и в аллокаторах. Это вы можете сами посмотреть

PS фиг знает, нормально я объяснил или нет. Надеюсь поймете все
 
Текущее время: 22:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru