Почему Microsoft использует struct, а не class в новом коде? - PullRequest
0 голосов
/ 16 января 2020

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

Я просматривал код в заголовочных файлах для vcpkg (менеджер упаковки библиотек, который Microsoft создает и является "новым" кодом), потому что чтение кода, как правило, является хорошим способом изучения вещей, которые вы не делали знаю.

Первое, что я заметил, было использование using вместо typedef.

Фрагмент из 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/parse.h'

template<class P>
using ParseExpected = ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;

Я лично раньше не использовал using таким образом и ответ от: В чем разница между «typedef» и «using» в C ++ 11? . По сути, using - это новый способ сделать это, и преимущество в том, что он может использовать шаблоны. Поэтому у Microsoft была веская причина использовать using вместо typedef.

Глядя на 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/commands.h', я заметил, что они не использовали никаких классов. Вместо этого это были только пространства имен с функцией или около того в них. ie:

namespace vcpkg::Commands
{
    namespace BuildExternal
    {
        void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
    }
}

Я предполагаю, что часть этого в том, что вызывающий синтаксис выглядит по сути как функция-член stati c в классе, поэтому код выполняет то же самое, но, возможно, сохраняет некоторые накладные расходы, будучи пространством имен вместо класса. (Если у кого-то тоже есть идеи по этому поводу, это было бы замечательно.)

Теперь суть всего этого. Почему Microsoft использует структуры вместо классов в своих пространствах имен?

Фрагмент из 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/parse.h':

namespace vcpkg::Parse
{
    /* ... Code I'm excluding for brevity ... */

    struct ParagraphParser
    {
        ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {}

        void required_field(const std::string& fieldname, std::string& out);
        std::string optional_field(const std::string& fieldname) const;
        std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const;

    private:
        RawParagraph&& fields;
        std::vector<std::string> missing_fields;
    };
}

Поиск в стеке потока Я нашел старый вопрос: Почему Microsoft использует структуру для библиотеки DirectX вместо класса? Какие ответы были по сути, вам не нужно объявлять вещи как publi c по умолчанию и способ комментирования внизу говорится, что это был старый код.

Если бы vcpkg был старым кодом, я был бы полностью удовлетворен, однако, это новый код. Это просто какой-то стиль, который у них есть, это перенос (но using против typedef нет)? Или это сохранить строку кода (public:)? Или есть какая-то накладная выгода? Или какая-то другая вещь, которую я вообще не рассматривал?

Ответы [ 3 ]

4 голосов
/ 16 января 2020

Различия только между struct и class:

  1. доступ к элементу по умолчанию (public против private) и

  2. наследование по умолчанию , если вы наследуете от типа (publi c наследование против частного наследования).

Конечный результат 1 будет таким же, как только автор завершит добавление public: / private: к типу. 2 вы можете легко контролировать себя, будучи явным при наследовании, а не полагаться на значение по умолчанию. Это вряд ли имеет большое значение и не имеет большого значения.

Что касается , почему Microsoft использует struct вместо class в их коде, у вас будет спросить некоторых сотрудников Microsoft.

1 голос
/ 16 января 2020

Относительно свободных функций по сравнению со стандартными c функциями, я не думаю, что в этом есть какие-либо издержки с классами (я вообще не измерял это, я просто подумал бы, что большинство компиляторов признают, что класс в основном просто пространство имен для функции). Дело в том, что вам не нужен класс.

Использование класса только с функциями stati c в основном нарушает класс как пространство имен. Так что если вы только делаете это, то будьте откровенны в этом и просто используйте пространство имен. Наличие там класса может быть только запутанным, поскольку вы можете подумать, что, возможно, здесь может быть какое-то состояние, и просто увидеть, что это не так, когда вы видите, что функция в классе является stati c.

Это особенно актуально, если это используется немного неправильно. Представьте, что кто-то создает экземпляр класса A a с функцией-членом stati c f для вызова a.f(). С производительностью проблем нет, так как конструкция не работает, и будет в значительной степени эквивалентна A::f(). Но читателю кажется, что в этом есть какое-то состояние, и это просто сбивает с толку.

Относительно двух других: using просто превосходит typedef благодаря возможности использовать шаблоны и имеет ( ИМО) лучше читается. Проблема struct против class - это нечто большее, чем те, которые имеют лучшие значения по умолчанию, это не большая разница, но чаще всего вам нужно то, что делает struct, поэтому нет смысла использовать class.

1 голос
/ 16 января 2020
  1. Быть (более) совместимым с C
  2. Чтобы не делать все публиковать c, используя ключевое слово public:, так как все объекты COM, например, имеют только publi c функции-члены.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...