• Как распределять свои проекты?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Вам нужно освоить три вещи.

    1. Управление версиями. Чтобы исходники лежали в положенном месте вместе с историей всех-всех-всех файлов, а также с зависимостями. Это будет git

    2. Управление сборкой. Чтобы из ваших исходников собирался нужный вам продукт в нужной конфигурации. Причем от 0 до инсталляторов под все-все-все платформы. Это будет cmake

    3. IDE. Это такой умный редактор текстов, который интегрирует управление первым и вторым. Тут можно брать любой во вкусу. VC++ хорошо идет.
    Ответ написан
    1 комментарий
  • Объясните пожалуйста смысл строк(указатели)?

    @Mercury13
    Программист на «си с крестами» и не только
    Перед нами структура данных под названием «односвязный список». У каждого элемента ссылка на следующий, у всей очереди ссылка на голову (front) и иногда на хвост (rear).

    Для чего нужна проверка на заполненность — непонятно, ведь ёмкость списка не ограничена и единственный способ убедиться, что очередь полна — завести память под новый элемент. Выпадает авария std::bad_alloc — значит, памяти не хватило. Если только для каких-то прикладных нужд: так, в StarCraft очередь на строительство пять юнитов, и точка. (Есть другой тип очереди, т.н. циклическая очередь — вон там ограничено.)

    Как работает enqueue: создаём новый элемент, следующий за ним — nullptr. Если очередь пуста, направляем на него front и rear. В противном случае пристраиваем его за тем, на который «смотрит» rear, и перенаправляем rear. Таким образом, «направляем rear» можно вынести за скобки, а остальные два исполнить в зависимости от пустоты очереди.
    Ответ написан
    3 комментария
  • Объясните пожалуйста смысл строк(указатели)?

    JaxxDexx
    @JaxxDexx
    Очень просто! Когда вы добавляете новый элемент в свою очередь, rear указывает на ваш последний элемент в очереди. Его next установлен в nullptr, поэтому чтобы не потерять связь между последним элементом в очереди и тем, который вы добавляете, вы устанавливаете указатель rear->next на адрес нового элемента. А после этого всей своей очереди говорите, что теперь новый элемент имеет адрес add (rear = add).
    Ответ написан
    6 комментариев
  • В чем здесь ошибка (конструктор)?

    Ошибка в этой строке:
    Node * front, rear;

    Только front является указателем на структуру. В конструкторе класса вы передаёте в конструктор rearint (nullptr).

    Ошибки не будет, если оба значения будут указателями:
    Node *front, *rear;
    Ответ написан
    Комментировать
  • Зачем использовать квалификатор const в возвращаемом значении?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    const String& String::test(const String&)const;
    Зачем в возврат указывать квалификатор const?

    Там же ссылка возвращается, чтобы строку по ссылке не поменяли.
    Ответ написан
    3 комментария
  • В чем здесь ошибка (перегрузка операторов)?

    @Mercury13
    Программист на «си с крестами» и не только
    Вы наладили операцию String << ostream → ostream. Надо наоборот, ostream << string → ostream.

    Такую операцию можно наладить только за пределами класса (возможно, как friend).
    Ответ написан
    1 комментарий
  • В чем здесь ошибка (перегрузка операторов)?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Оператор << и любая арифметика делаются путем объявления функций вне класса
    Ответ написан
    Комментировать
  • Что будет с объектом если вызвать несколько раз его конструкторы?

    Вторая запись это не вызов конструктора, а оператор присваивания.

    Сначала создавасться новый временный объект через второй конструктор (т.к. конструктор является implicit, то допустимо неявное преобразование из int в CClass). Затем у первого объекта вызовется оператор присваивания с временным объектом в качестве параметра.

    В C++ без сложных манипуляций невозможно второй раз вызвать конструктор.

    Фактически ваш код эквивалентен этому:

    CClass obj(); // на самом деле так писать нельзя, это не вызов конструктора а объявление функции
    
    obj = CClass(1);
    Ответ написан
    32 комментария
  • Почему эта функция возвращает объект (перегрузка операторов)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Вопрос: в return я умножаю два int, функция возвращает копию Factory, почему так?

    Потому что ты так определил этот оператор. Написал бы int Factory::operator * -- всё было бы по-другому.
    Если твой вопрос "почему это компилируется", то ответ -- потому что у Factory есть не-explicit конструктор, который можно вызвать с параметром типа int. Этот конструктор создаёт объект возвращаемый из оператора *.
    Ответ написан
    1 комментарий
  • Как понять, где ссылка и где копия?

    devalone
    @devalone
    ̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
    На стеке создаётся область, куда копируется значение, например тут:
    void doSomething(Type obj);
    Объект при передаче будет скопирован, т.е. выделится память на стеке(сдвинется указатель стека) и вызовется конструктор копирования, а после при выходе из функции деструктор
    void doSomething(Type &obj);
    копирования не произойдёт, т.к. передастся адрес, вообще стандарт не гарантирует, как именно реализованы ссылки но обычно как указатели. Т.е. можно думать о ссылке как об указателе с синтаксическим сахаром.
    как можно вернуть псевдоним (ссылку) на тип, который размещается не в управляемой куче и вообще почему на него можно создать указатель

    а почему нет? Если речь про стек, то создать то можно, другой вопрос, что указывать после выхода из функции он будет на мусор
    Type& doSomething(Type& obj) {
    	Type anotherObj = obj;
    	return anotherObj;
    }
    int main() {
            // .... 
    	Type &obj = doSomething(something);
    	// здесь при работе c obj будет UB
            // .... 
    }
    Ответ написан
    Комментировать
  • Как понять, где ссылка и где копия?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    С управляемой кучей я все понял, еще я не могу понять, как можно вернуть псевдоним (ссылку) на тип, который размещается не в управляемой куче и вообще почему на него можно создать указатель

    На самом деле разница между "кучей" и "не кучей" не такая и большая с точки зрения указателей.
    У нас есть 3 варианта размещения переменных:
    1. Куча. int* a = new int(3);
    2. Стек. int b = 5;
    3. Константная память, инициализируемая на старте приложения. char* c = "hello world";


    С точки зрения процесса есть большой непрерывный кусок памяти, который называется виртуальная память.
    Куча это кусок этой памяти, который хранит сами данные плюс некоторую служебную информацию, которая позволяет например находить свободные места в памяти.
    Стек это другой кусок, для которого дополнительно хранится указатель на "голову", который мы сдвигаем при push и pop. Но данные по прежнему в том же большом куске виртуальной памяти с той же адресацией.
    Константная память это третья зона с самым простым устройством. Туда записываются значения при старте программы и больше не меняются до конца ее работы.

    Также полезно понимать что ссылка и указатель это по сути одно и то же "под капотом". Просто в языке работа с ними выглядит немного по-разному. Ну и ссылка имеет меньше возможностей (а значить меньше простор для ошибки) вроде указывания в никуда (nullptr).

    Таким образом мы можем взять указатель или ссылку на переменную вне зависимости от ее местоположения. По сути это просто порядковый номер ее начала в виртуальной памяти.

    Копия это отдельный участок в памяти. Указатели на оригинал и копию будут иметь разные значения. при изменении копии оригинал не будет затронут.
    Аналогия с почтовыми адресами более чем уместна. Адрес дома записанный на бумаге - указатель. Сам дом по этому адресу - значение. Создание копии - построить такой же дом в другом месте города. Адрес у копии дома будет разумеется другой.
    Ответ написан
    2 комментария
  • Какую литературу выбрать для изучения WINAPI?

    @Fil
    С ума сошли предлагать Руссиновича. Книга крутая, но точно не первая для ознакомления с ОС. Рихтера советую, это тоже классика
    Ответ написан
    Комментировать
  • Какую литературу выбрать для изучения WINAPI?

    Stalker_RED
    @Stalker_RED
    Вообще, в книгах Марка Руссиновича довольно круто все это описывается. Но боюсь, что уровень там не для совсем начинающих.
    Ответ написан
    Комментировать
  • Какую литературу выбрать для изучения WINAPI?

    @res2001
    Developer, ex-admin
    PVOID - void*
    PWSTR - wchar_t *
    HANDLE - просто целое, подробностей, обычно, знать не нужно - это идентификатор объекта (хэндл).
    И берите Русиновича по совету 15432
    Ответ написан
    3 комментария
  • Какую литературу выбрать для изучения WINAPI?

    @dmshar
    Еще немного классики.
    https://www.ozon.ru/context/detail/id/2575245/
    Довольно доходчиво написано.
    Ответ написан
    Комментировать
  • В чем отличие многобайтовой кодировки от Юникода?

    https://msdn.microsoft.com/ru-ru/library/cwe8bzh0.aspx
    https://ru.wikipedia.org/wiki/DBCS
    До появления Unicode тоже были кодировки с размером символа более байта.
    Ответ написан
    Комментировать
  • Что означает _t в типе wchar_t?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Это называется GNU/POSIX naming agreement - соглашение об именовании.
    The requirement that additional types defined in this section end in "_t" was prompted by the problem of name space pollution. It is difficult to define a type (where that type is not one defined by POSIX.1-2008) in one header file and use it in another without adding symbols to the name space of the program. To allow implementors to provide their own types, all conforming applications are required to avoid symbols ending in "_t", which permits the implementor to provide additional types. Because a major use of types is in the definition of structure members, which can (and in many cases must) be added to the structures defined in POSIX.1-2008, the need for additional types is compelling.


    Таким образом, для избежания пересечения имени типа с именами других сущностей, для имен типов определяется суффикс "_t".

    Дополнительно, GNU резервирует полностью все пространство имен для суффикса "_t" с целью расширения набора имен стандартных типов.

    В общем, суффикс "_t" несет двойной смысл. Первое - он говорит что это имя типа. Второе - он говорит что это имя стандартного типа.
    Ответ написан
    1 комментарий
  • Почему не работает этот код с ссылками?

    terrier
    @terrier
    using namespace std;

    Вот не надо так делать и не будет подставляться std::swap (который как известно возвращает void) вместо вашего варианта swap
    P.S. Ну, и, конечно сама функция swap, которая не свапает - это тоже достойно.
    Ответ написан
    1 комментарий
  • В чем различие между объявлением с new и без него?

    @res2001
    Developer, ex-admin
    new выделяет память в куче, а определение без new - на стеке, со всеми вытекающими преимуществами и недостатками. Нужно понимать когда определять объект в куче, а когда на стеке.
    Ответ написан
    Комментировать