170 похожих чатов

Благодарю за пояснения выше. Теперь пойду уточнять для себя различия

между методом и функцией. Дружественной или нет. Свободной и члена-класса.

Как я понимаю, вот мои заблуждения, в которых мне предстоит разобраться:
1. Метод — это функция, описанная в теле или вне класса, для работы через экземпляры этого класса. Из этого следует мой неверный вывод: метод — это просто другое название для функции "внутри объекта класса" к которой можно обратиться через оператор доступа "точка". Из этого следовало, что в классе ничего не называется функцией (как оказалось, ошибка). Ключевое отличие метода — оператор доступа?
2. Значит, у класса есть не только методы, но и функции. Нужно понять, как различать эти сущности.
3. Нужно понять, что такое функция-член, свободная функция, чем они различаются.
4. Перегрузки операторов — отдельная сущность. Оказывается, это по сути тоже функция. Но не метод, потому что нельзя обратиться через оператор доступа.
5. Конструкторы и деструкторы — отдельные сущности или все таки тоже функции?
6. То, как я перегрузил оператор + бессмысленно, раз я в своём классе реализовал сеттеры и геттеры. Надо переделать под два параметра, тогда по непонятным пока что мне причинам доступ к полям класса пропадёт? Кажется, это как-то зависело от количества параметров, а от количества параметров как-то зависело, функция-член класса или свободная функция. Это как-то всё связано, но нужно выстроить цельную картину.

Пойду потихоньку гуглить, но буду рад любой помощи. Ещё раз спасибо!

22 ответов

15 просмотров

class foo { public: // спецификатор доступа // функция-член доступна через объект этого класса, по сути она содержит неявный параметр this void boo() {} // оператор foo operator +(const foo&other) { return *this; } // статическая функция-член static void static_func() {} }; ... foo a; foo b; foo c = a + b; // вызов оператора foo d = a.operator+(b); // можно и так вызвать оператор a.boo(); // вызов функции-члена foo::static_func(); // вызов статической функции-члена, она работает вне контекста текущего объекта ну и никаких методов в С++ нет, это просто по инерции мы используем этот термин из терминологии ООП для обозначения функций-членов

Владимир- Автор вопроса
Anatoly Shirokov
class foo { public: // спецификатор доступа //...

Исходя из примера я понял, что: Функция-член — это такая функция, которая доступна через объект этого класса. Метод — термин из терминологии ООП. Вот и путаница. В каком-то смысле — синонимичные термины. Перегрузка оператора — это действие над оператором. Мы прописываем, что оператор должен сделать с объектами класса. Но от этого оператор не перестаёт быть оператором. Т.е. такие сущности нужно называть операторами? Но в общем смысле получается, что оператор — это в каком-то смысле функция? А в контексте перегрузки оператора для класса — функция-член? Я всё ещё не могу понять, почему перегрузка с одним параметром была названа функцией-членом, а с двумя — свободной функцией. Получается, если я буду перегружать оператор через два параметра, я пропишу, что не хочу, чтобы этот оператор был функцией-членом, т.е. не хочу, чтобы у него был неявный указатель this. Поэтому пишу два параметра. Поэтому у меня нет доступа к приватным полям класса? Правильно ли я понял разницу? foo d = a.operator+(b); Не знал про это. Это помогает лучше прочувствовать взаимосвязь всего со всем. Вроде бы оператор, а вроде бы тоже могу его вызвать. А значит тоже своего рода функция. А термины созданы для того, чтобы различать, классифицировать функции, различать сущности. Понял разницу между static и regular функциями-членами на наглядном примере. Большое спасибо за ответ!

Владимир- Автор вопроса
Stas
почему вы называете это "перегрузками"?

В интернете начитался. Например пишут: «Перегрузка операторов позволяет определить действия, которые будет выполнять оператор. Перегрузка подразумевает создание функции, название которой содержит слово operator и символ перегружаемого оператора.» Или вот ещё: https://docs.microsoft.com/ru-ru/cpp/cpp/operator-overloading?view=msvc-170 После того, как задался всеми этими вопросами, стало ясно, что оператор, вот это всё, это всё таки тоже функция. Путаница в терминах, моя невнимательность. А ещё мне казалось, что есть схожесть с перегрузкой функции, когда у функции одно название, но разные сочетания параметров (количество, типы). Но видимо я что-то напутал.

Владимир
В интернете начитался. Например пишут: «Перегрузка...

понятно. хотя термин немного некорректный. потому что перегрузка заменяет одно другим

Владимир
В интернете начитался. Например пишут: «Перегрузка...

перегрузку оператора можно оформить как член класса: struct foo { foo operator+(const foo& other); }; так и свободной функцией: struct foo { }; foo operator+(const foo& left, const foo& right) {...} достоинство у второго варианта в том, что можно перегружать оператор для произвольных типов: foo operator+(int left, const foo& right) {...} если они имеют смысл для вашего класса

Stas
понятно. хотя термин немного некорректный. потому ...

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

Владимир- Автор вопроса
Anatoly Shirokov
перегрузку оператора можно оформить как член класс...

Технически оба варианта можно произвольно вносить/выносить из тела класса? Если да, получается, считается хорошим тоном, операторы, которые функции-члены, оставлять внутри тела класса (смысловая связь с наличием this), а те, которые свободные функции, выносить из тела класса (потому что у них нет this, нет доступа к полям)?

Владимир
Технически оба варианта можно произвольно вносить/...

Это обязательная принципиальная разница. Вы не можете определить бинарный оператор методом с более чем одним параметром (пока что).

Владимир- Автор вопроса
Sergey Anisimov
Это обязательная принципиальная разница. Вы не мож...

Т.е. в данном случае вынесение за тело класса — это не просто стиль кода?

Владимир
Т.е. в данном случае вынесение за тело класса — эт...

Вы можете вынести определение, но оно должно оставаться консистентным с объявлением (которое, в случае выбора метода, будет иметь один параметр).

Владимир
Технически оба варианта можно произвольно вносить/...

есть набор операторов, которые могут быть только функциями членами. operator=, operator[], operator-> и operator()

Владимир
Т.е. в данном случае вынесение за тело класса — эт...

внешние операторы позволяют расширят интерфейс класса без изменения его кода. самый наглядный пример это классы std::ostream и std::istream. что бы задать функции сериализации какого-то своего типа, не надо добавлять новые операторы в ostream/istream, достаточно определить свободный операторы. дальше уже ADL сделает всю работу

Владимир- Автор вопроса
Sergey Anisimov
Вы можете вынести определение, но оно должно остав...

К своему стыду, я ещё ни разу не встречался с термином «консистентность». Сейчас потихоньку в интернете ищу информацию.

Владимир
К своему стыду, я ещё ни разу не встречался с терм...

Это и не термин. Edit: Ну или не языковой, по крайней мере... Edit: Я это имел в виду: struct Struct { auto operator + ( int ) -> Struct; }; auto Struct::operator + ( int ) -> Struct { /* ... */ }

Владимир- Автор вопроса
Sergey Anisimov
Это и не термин. Edit: Ну или не языковой, по край...

Я пытаюсь понять, что именно вы хотели сказать. Что-то нашёл про согласованность данных. Т.е. про какой-то смысл, заложенный в структуру данных. В общем, я могу вынести определение функции-члена за тело класса, если это не нарушает смысла, заложенного в этот класс? P.S. к сожалению, я не понимаю кода, который вы приложили. Но всё равно спасибо за наводку, постараюсь разобраться

Владимир- Автор вопроса
Stas
внешние операторы позволяют расширят интерфейс кла...

Спасибо за пример! По поводу свободной функции, почему её объявили вне класса, стало намного понятнее

Владимир
Спасибо за пример! По поводу свободной функции, по...

Если интересна идейная составляющая вопроса https://youtu.be/WLDT1lDOsb4

Владимир
Я пытаюсь понять, что именно вы хотели сказать. Чт...

Если это определение согласуется с объявлением (разница неформально). В моем примере выше в пределах определения Struct был объявлен метод operator+(), "перегружающий" сложение с int, после чего, уже за пределами определения Struct, было предложено определение этого метода. Из потенциально "новых" синтаксических особенностей: - auto можно писать на позиции типа возвращаемого значения, если этот тип можно контекстно вывести, либо если он указывается в рамках trailing-return-type (посмотрите здесь грамматику (2)), т.е. после -> как в примере. int sub ( ); и auto sub ( ) -> int; эквивалентны. - Имена параметров опциональны в объявлениях и определениях: int sub ( int ); и int sub ( int i ); эквивалентны.

Тебе надо было СЛАТЬ КОД, а не рассуждать. (т.е. слать код и + к этому рассуждать)

Всё не так...

Вывод - идти читать учебник и/или cppreference.com

Похожие вопросы

Обсуждают сегодня

Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
55
Привет, нужен совет старших товарищей. Есть глобальная переменная var DefaultDataFolder:string; инициализируем DefaultDataFolder:='a:\_OUT\'; есть примитивная процедур...
Max Otto
11
Вопрос. Теоретический. Есть список команд. Команды отправляю в обработку некой функции, по очереди. Разные команды могут давать разные результаты после обработки. В зависимос...
Serjone
7
Всем вечера. Подскажите как лучше сделать. делаю на Д10 Например будет база данных на SQLite. в ней будет много таблиц. более 50шт Типа справочник. Содержать ID Name Id p...
Андрей Т 🐎
10
это группа токсиков или тех кто помогает?
Ибрагим
9
Я короче решил скомпилировать Nim в js, я думал он сработает как обычный транслятор. По итогу он мне создал файл с расширением js, и туда поместил кучу кода Вопрос, что это з...
𝕾𝖍𝖆𝖉𝖊 <suspense>
8
мы пытаемся подменить функцию, которая имеет меньше инструкций относительно функции, которой подменяем. https://www.reddit.com/r/jailbreakdevelopers/comments/w06ujy/mshookfun...
Óðinn
6
У кого-нибудь есть под рукой функция кодирования юникода, которая из фразы На русском сделает \u041d\u0430\u0020\u0440\u0443\u0441\u0441\u043a\u043e\u043c ?
Daniil Smolyakov
7
подскажите пожалуйста, как мне освободить результат записанный в переменную result? в чем проблема подскажите если МОЖЕТЕ?
Михаил Helper
28
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
Карта сайта