Задать вопрос
  • Почему в C++ всё именно так?

    @MarkusD Куратор тега C++
    Денис Загаевский,
    С моим незнанием С++ видно, что ответ не очень.

    Есть такой подход: Критикуя - предлагай.
    Ознакомься с тем, как этот подход работает у меня: [1], [2], [3], [4], [5].
    Приходишь и аргументированно, со ссылками на достоверные источники, предлагаешь альтернативу.

    У тебя же пока получаются только чайка-коммуникации. Собственно, отношение к тебе у все большего числа людей будет как к чайка-собеседнику.
  • Почему в C++ всё именно так?

    @MarkusD Куратор тега C++
    Денис Загаевский, понимаю, я видел твои ответы без претензии на знание языка. :)
    Я так понимаю, сейчас ты пришел таки постебаться?
  • Почему в C++ всё именно так?

    @MarkusD Куратор тега C++
    Бобби Шифер,
    Извините, вы меня хотите проэкзаменовать?

    Вряд ли. :) Дениска в плюсах не разбирается от слова вообще, он сюда заходит только потоксичить на тему ущербности плюсов.
  • Почему в C++ всё именно так?

    @MarkusD Куратор тега C++
    Игорь Журавлёв, стоит обратить внимание на П3.7 регламента работы сервиса.
    3. В процессе создания вопроса пользователь Сервиса обязан:
    Не размещать несколько разнородных вопросов в рамках одного вопроса.

    Пояснение П3.7 дает понять что связь между дополнительными вопросами должна быть очень тесная.

    От себя. Тебе все-таки стоило разбить свой текст на отдельные вопросы и задавать их поступательно, добиваясь решения каждого вопроса. Сейчас ты убежал вперед лошади что везет тебя, ошибся уже в первом вопросе потому что стандарт не запрещает того что ты спрашиваешь, но код у тебя в первом же вопросе неправильный и не соответствует вопросу.
    Обрати внимание на правила неявного приведения типов к модифицированным.
  • Какие существуют средства для работы с документами Word.docs (.doc) через c++?

    @MarkusD Куратор тега C++
    darkoment, а, ясно.
    Помимо всего вышеперечисленного могу еще предложить заглянуть в исходники Open Office. Там должен быть уже готовый код для работы с необходимыми тебе форматами файлов.
  • Как исправить ошибку в коде С++?

    @MarkusD Куратор тега C++
    1HAWK1 , а почему std::gets [?] должна присутствовать в твоей стандартной библиотеке?
  • Какой код правильнее?

    @MarkusD Куратор тега C++
    Игорь Журавлёв, в таком случае ответ на твой вопрос будет таким.
    Не используй в своем коде неизвестные тебе конструкции.
    Твой код всегда должен быть полностью понятен тебе, как писателю, и, обязательно, должен быть понятен читателю в каждой своей строчке.

    Понятной для любого читателя конструкцией будет только первый вариант. Второй будет только вызывать вопросы, один из которых - мой, как вопрос читателя.
  • Какой код правильнее?

    @MarkusD Куратор тега C++
    Игорь Журавлёв , какова цель присутствия auto во втором случае?
  • Почему не вызвался конструктор копирования и деструктор?

    @MarkusD Куратор тега C++
    klajowski, ты сейчас волен сам написать ответ на вопрос и отметить его решением. :)
  • Почему не вызвался конструктор копирования и деструктор?

    @MarkusD Куратор тега C++
    klajowski,
    конструктор копирования должен вызываться при копирующей инициализации

    Крайне спорное утверждение. Я, согласно стандарту, вижу тут только один конструктор преобразования.
    В деталях там действительно присутствует Value Initialization [?] и Copy Initialization [?], но Copy Elision [?] этот код всегда и строго оптимизирует до ровно одного Value Initialization.
  • Почему не вызвался конструктор копирования и деструктор?

    @MarkusD Куратор тега C++
    klajowski, тогда у тебя точно нет оснований требовать вызвать конструктор копирования в месте получения результата от fillArray. :)
    У тебя там работает NRVO, если коротко.
    Обозначенным конструктором преобразования конструируется a прямо из main, после чего код fillArray выполняет ряд описанных в нем присвоений.
    return в fillArray становится фиктивен, а локальная переменная выпадает из кода за ненадобностью.
    Это все - результат работы NRVO - Named Return Value Optimization.
  • Почему не вызвался конструктор копирования и деструктор?

    @MarkusD Куратор тега C++
    klajowski , каким стандартом языка ты пользуешься для изложения этого кода?
    Пока я не вижу предпосылок к тому чтобы конструктор копирования у тебя должен был вызваться.
  • Для чего объявляется вложенная структура (или класс) перед тем, как она объявляется дружественной?

    @MarkusD Куратор тега C++
    Qubc, давай немного ясности внесу. Ответ пусть так и остается решением.
    struct Pointer; - это предварительное объявление структуры в пространстве имен типа Holder.
    friend struct Pointer; - тут нужно проявить внимательность.
    Обратимся к описанию (3) из документации.
    The name of the class that is used in this friend declaration does not need to be previously declared.

    Это - предварительное объявление структуры с указанием ее дружественности. Вопрос только в том, к какому пространству имен относится это предварительное объявление? Ответ тоже есть в документации по дружественности.
    When a local class declares an unqualified function or class as a friend, only functions and classes in the innermost non-class scope are looked up, not the global functions

    Такой поиск имени напоминает Unqualified name lookup [?].
    Иными словами, предварительное объявление дружественной структуры Pointer будет произведено в том пространстве имен, где определен тип Holder, а не в его пространстве имен.

    Теперь собираем код в кучку. Чтобы дружественной была назначена именно структура Holder::Pointer, требуется сперва сделать предварительное объявление структуры Pointer в пространстве Holder.
    В это же время стоит обратиться к описанию (4) из документации дружественности. Начиная с C++11 можно пользоваться формой friend Pointer; чтобы использовать уже объявленное имя вместо создания предварительного объявления этого имени.

    По итогу лишним в твоем коде является только слово struct в строке friend struct Pointer;. Да и то только если ты пользуешься C++11.
    В остальном обе строки создают точное понимание того, какой именно тип ты хочешь объявить дружественным.

    В качестве дополнения:
    Структура, объявленная как вложенная, не получает автоматического доступа
    к закрытым членам внешней структуры.

    Это все враки. Документация по вложенным типам говорит иное.
    Like any member of its enclosing class, the nested class has access to all names (private, protected, etc) to which the enclosing class has access ...

    Поэтому лишним в данном случае является как предварительное объявление Pointer, так и объявление его дружественности. С поправкой, конечно, на C++11.
  • Что именно делается константным при таком определении типа?

    @MarkusD Куратор тега C++
    Wataru, я не ради спора, но для того чтобы как можно больше людей объяснялись общей и задокументированной терминологией.
    Давай обратимся к документации на ссылки.
    //  r2 += "!";               // error: cannot modify through reference to const
    ...
    const std::string& r2 = s1 + s1; // okay: lvalue reference to const extends lifetime
    ...
    std::cout << "lvalue reference to const overload f(" << x << ")\n";
    ...

    Note that rvalue references and lvalue references to const extend the lifetimes of temporary objects


    По-английски это звучит именно как reference to const.

    Еще давай обратимся к документации на константность.
    For any type T (including incomplete types), other than function type or reference type ...

    Константность применима для любого типа, кроме типа функции и типа ссылки.

    И ниже еще:
    References and pointers to cv-qualified types may be implicitly converted to references and pointers to more cv-qualified types.

    Т.е. это не cv-ссылки, это - ссылки на cv-типы.

    Разница очень большая и отсутствие понимания этой разницы вводит в заблуждение автора вопроса.
  • Что именно делается константным при таком определении типа?

    @MarkusD Куратор тега C++
    Или это ссылка на константный вектор? Константные ссылки в природе бывают? :)
  • Как привести шестнадцатеричное число к hex виду?

    Zorgios, твой вопрос абсолютно непонятен. Тебе нужно переформулировать его, скорее всего, сопроводив как можно большим набором примеров кода.
  • Как правильно выстроить логику кода с соблюдением принципов ООП?

    @MarkusD Куратор тега C++
    Ben L, Давай коротко опишу суть без ссылок.
    Во время определения типа задается несколько интерфейсов, среди которых есть родительский интерфейс типа, публичный интерфейс, интерфейс наследников типа и приватный интерфейс типа. Интерфейс - это форма обращения, это набор функций, которые могут быть использованы для изменения состояния экземпляра типа.
    Состояний у типа тоже может быть несколько: все те же родительское состояние, публичное состояние, приватное состояние, состояние наследников.
    Терминами C++ это все выражается через определение области доступа. Функции в области protected: формируют интерфейс наследников. Поля в области private: формируют приватное состояние. Соответственно, публичный интерфейс типа определяется через функции в области public:. При этом, даже если в публичном интерфейсе есть константная функция-геттер, которая просто возвращает константную ссылку на приватное поле, то это не доступ к приватному полю. Это именно публичный интерфейс, который строго ограничивает возможности работы с состоянием экземпляра и именно так обеспечивает инвариантность этого состояния.

    Adamos в своем ответе писал о том, что необходимость обращения к приватному состоянию экземпляра из стороннего кода является ярким признаком плохого дизайна. Часто плохой дизайн реализуется через дружественность, поэтому дружественность так часто и обличается признаком плохого дизайна.
    В ответ на твой вопрос "Как этого можно добиться на практике?" можно сказать что плохой дизайн следует просто исправлять.
  • Как правильно выстроить логику кода с соблюдением принципов ООП?

    @MarkusD Куратор тега C++
    Ben L, видимо с термином инварианта ты не знаком.
    Можно добавить getter-ы в interface.

    Еще раз. Минуя публичный интерфейс типа?
    Ты точно понимаешь мои слова? Что такое публичный интерфейс типа?
  • Как правильно выстроить логику кода с соблюдением принципов ООП?

    @MarkusD Куратор тега C++
    lipa44, хорошо, спасибо.
    // Грани кубика
    Plane UpPlane;
    Plane DownPlane;
    Plane LeftPlane;
    Plane RightPlane;
    Plane FrontPlane;
    Plane BackPlane;

    С этим тебе будет тяжело работать. Тебе ведь надо вращать строки на гранях. При этом, крайние строки на гранях приведут к вращению смежной грани. Вот с таким дизайном тебе будет неудобно. Придется писать много лишнего кода.
    Легче обозначить просто 6 граней в массиве, попутно определяя закон их смежности на ребрах.
    Кубик состоит из 6 граней, в каждой из которых N*N ячеек с цветом. Нас интересует только цвет ячейки. Всего цветов тоже 6. Цвета можно обозначить целыми числами от 0 и до 5.

    vector<vector<vector<MiniCube>>> arr;
    Это память решения? Этому тут не место. Представь что в другой ситуации ты просто дал кубик игроку покрутить. Зачем игроку это поле для игры? В кубике должны быть только свойства кубика. Еще в кубике должна быть функциональность от кубика. Снова представь игрока с кубиком, нужно ли ему что-то дополнительное чтобы крутить его? Не нужно ведь. Следовательно, у кубика должен быть интерфейс крашения его строк.

    #include "cubeSolving.h" // алгоритмы решения
    Если мы дадим кубик игроку, то зачем ему еще и информация о его решении? Этому заголовку тут не место.

    #include "rubikCube.h"
    Вот это уже на месте. Когда ты обращаешься к решениям кубика, тебе уже нужна информация о самом кубике и, собственно, сам кубик.

    cubeSolving() = default;
    А для кого решать будем? Сюда стоит передать ссылку на кубик, который и будем решать.
    В итоге у тебя игрок может взять кубик в произвольном состоянии, положить его в cubeSolving и ткнуть решалке решить.
    Решалка должна оперировать на переданном через конструктор кубике. Вращения она должна выполнять используя только публичный интерфейс кубика.

    Для того чтобы логика вращений не загружала класс кубика, ее можно вынести в тулкит - в отдельный тип, который через свой конструктор примет обозначенный выше массив из 6 граней по ссылке и предоставит интерфейс для вращения строк. При этом, публичный интерфейс кубика будет просто обращаться к этому тулкиту. Экземпляр тулкита даже в состояние кубика складывать не за чем, т.к. он все равно оперирует данными по ссылке.

    Сейчас у тебя получается каша из зависимостей и данных. ООП - это методика структуризации данных и функциональности. Выделяй свойства и назначения объектов, формируй типы этих объектов, устанавливай строгие однозначные связи между типами.
    Если тебе что-то не понятно, я могу немного детальнее описать.