Перейти к содержимому

Как передать класс в функцию c

  • автор:

Как передать объект класса по ссылке?

Если Вы «пытаетесь познать C++», то хотя бы книгу откройте по языку. Любую. Тогда таких вопросов появляться не будет.

21 июн 2016 в 18:02

Зря @ixSci читаете нравоучения. Q&A не для дискуссий и высоких материй. Вообще, сходу не нашел ответа на вопрос для Си++ в базе вопросов, так что сам по себе вопрос считаю адекватным, вот первый ответ, близкий по духу. Формулировка, вопроса конечно страдает, требуется правка. Лучше переформулируйте вопрос за автора, он просто не знает, что в нем написать. Думаю, против ни кто не будет.

21 июн 2016 в 18:41

Не понимаю, с чего вдруг Вы тут разводите цензуру. Не нравится вопрос — поднимайте тревогу, пусть модераторы решают. Совсем не обязательно дергать самолюбие авторов. Я вообще такие вопросы пропускаю мимо ушей. Этот привлек внимание как раз отрицательной оценкой.

22 июн 2016 в 8:04

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Передача объекта по ссылке используется достаточно часто и описана во многих книгах по С++, однако не всем получается быстро понять данный механизм.

Для начала рассмотрим принимающую сторону, т.е. функцию или метод класса, в который передается ссылка на объект. В простейшем случае это выглядит так:

void foo(ObjectType& object) 

К типу передаваемого объекта добавляется символ & , причем его можно размещать как вплотную к типу, так и к имени объекта. Это зависит от стиля программирования.

При передачи объекта по ссылке не происходит копирования, т.е. мы по сути передаем адрес на объект, что быстрее и менее затратно по памяти. Плюс ко всему мы работаем непосредственно с объектом, переданным по ссылке. Если же объект исключительно входной и не должен быть изменен, то следует добавить модификатор const:

void foo(const ObjectType& object) 

Теперь, изменить объект object в функции не получится. Чтобы было возможно вызывать методы класса object они должны быть объявлены как const . Следует отметить, что есть понятие «ссылки на константу» а есть «константная ссылка». В данном случае мы имеем дело с первым понятием.

Теперь перейдем непосредственно к передаче объекта. Тут есть три варианта:

ObjectType myObject; foo(myObject); 
ObjectType* myObject = new ObjectType(. ); foo(*myObject);` 
ObjectType& myObject = otherObject; foo(myObject); 

c++ Передать метод одного класса в качестве параметра для метода другого кдасса

Здравствуйте. C++ . Есть две переменные, одна класса А, вторая класса B. Как бы передать нестатический метод 1 первого объекта в нестатический метод 2 второго объекта в качестве калбэк функции. При этом данная калбэк функция должна иметь доступ к членам своего объекта через this.
Пожалуйста, не отсылайте к гуглу. Перечитал несколько руководств, пока не получается.

rumgot ★★★★★
17.11.15 17:16:29 MSK

friend не вариант?

Kiborg ★★★
( 17.11.15 17:18:50 MSK )

лямбда, std::function (std::bind)

ossa ★★
( 17.11.15 17:19:02 MSK )
Gvidon ★★★★
( 17.11.15 17:19:27 MSK )

#include #include using std::cout; class A < public: void foo() < cout >; class B < public: using Cb = std::function; void go(Cb cb) < // some work cb(); >>; int main() < A a; B b; b.go([&a]() < a.foo(); >); > 

anonymous
( 17.11.15 17:25:21 MSK )

не надо так делать

udhv ★
( 17.11.15 17:30:27 MSK )
Ответ на: комментарий от udhv 17.11.15 17:30:27 MSK
anonymous
( 17.11.15 17:32:37 MSK )
Ответ на: комментарий от udhv 17.11.15 17:30:27 MSK

rumgot
Касскажи свой кейс, скорее всего это нужно длелать по-другому.

Kroz ★★★★★
( 17.11.15 17:34:29 MSK )

Или указатель на член или универсальное решение в духе std::function + лямбда/std::bind.

anonymous
( 17.11.15 17:34:41 MSK )
Ответ на: комментарий от anonymous 17.11.15 17:32:37 MSK

Объясни зачем существуют private/protected, по ходу найдешь ответ на свой вопрос.

Kroz ★★★★★
( 17.11.15 17:35:42 MSK )
Ответ на: комментарий от Kroz 17.11.15 17:35:42 MSK

Как существование private/protected влияет на возможность передать в метод колбек?

При этом данная калбэк функция должна иметь доступ к членам своего объекта через this.

Как это нарушает private/protected?

anonymous
( 17.11.15 17:37:47 MSK )
Ответ на: комментарий от Kroz 17.11.15 17:35:42 MSK

Как этот пример нарушает приватность?

anonymous
( 17.11.15 17:38:43 MSK )
Ответ на: комментарий от Kroz 17.11.15 17:35:42 MSK

Колбэки существовали и использовались всегда, никакого отношения к private/protected они не имеют.

Gvidon ★★★★
( 17.11.15 17:38:45 MSK )

какой стандарт? Если до 11, то гугли fastdelegate, если после, то есть стандартные средства для этого.

gavlig ★★★
( 17.11.15 17:53:24 MSK )

http://www.boost.org/doc/libs/1_59_0/doc/html/signals2.html или libsigc++2 если нужно общее решение. И сигналы/слоты в Qt, разумеется.

asaw ★★★★★
( 17.11.15 17:56:23 MSK )

Таки есть указатели на методы класса. Почитай хотя бы тут https://rsdn.ru/article/cpp/fastdelegate.xml#EGD

AF ★★★
( 17.11.15 18:10:53 MSK )
Ответ на: комментарий от AF 17.11.15 18:10:53 MSK

Указатели на члены не содержат в себе объект, его придётся прокидывать отдельно, что не очень удобно.

Gvidon ★★★★
( 17.11.15 18:14:54 MSK )

boost::bind на стороне передающего коллбэк, boost::function на стороне получающего коллбэк

Manhunt ★★★★★
( 17.11.15 18:21:05 MSK )
Ответ на: комментарий от Gvidon 17.11.15 18:14:54 MSK

Методу класса, если он конечно не статический, полюбому нужен обьект. И как ты его не прячь за синтаксическим сахаром, суть от этого не поменяется!

AF ★★★
( 17.11.15 19:42:29 MSK )
Ответ на: комментарий от AF 17.11.15 19:42:29 MSK

И пишешь ты, наверное, в бинарных кодах. А чё, всё остальное — это синтаксический сахар, не меняющий сути.

Gvidon ★★★★
( 17.11.15 20:06:38 MSK )

Твоя задача решаема, но как тебе уже сказали, скорее всего, тебе нужно что-то другое.

Callback-и в C++ оказываются востребованы либо для связи с «необъектным» кодом, либо при кривой архитектуре. Подозреваю, что класс A может реализовать интерфейс I, и вот указатель на него можно передать в B.

hobbit ★★★★★
( 17.11.15 20:10:35 MSK )
Ответ на: комментарий от hobbit 17.11.15 20:10:35 MSK

Callback-и в C++ оказываются востребованы либо для связи с «необъектным» кодом, либо при кривой архитектуре.

Функторы, которые предлагается передавать в алгоритмы STL, как раз являют собой пример таких коллбэков. STL, может быть, и «необъектный», но вполне себе C++-ный.

Manhunt ★★★★★
( 17.11.15 22:15:27 MSK )
Ответ на: комментарий от AF 17.11.15 19:42:29 MSK

Методу класса, если он конечно не статический, полюбому нужен обьект. И как ты его не прячь за синтаксическим сахаром, суть от этого не поменяется!

За то поменяется объем портянки. Доля букв, посвященных бойлерплейту — сократится, а доля букв, посвященных смыслу вещей — возрастёт.

Manhunt ★★★★★
( 17.11.15 22:21:19 MSK )
Последнее исправление: Manhunt 17.11.15 22:21:27 MSK (всего исправлений: 1)

Как бы передать нестатический метод 1 первого объекта в нестатический метод 2 второго объекта в качестве калбэк функции

Ты хочешь неправильно.

no-such-file ★★★★★
( 18.11.15 05:28:17 MSK )
Ответ на: комментарий от Manhunt 17.11.15 22:21:19 MSK

Что хорошо опытному девелоперу на практике, то не всегда хорошо новичку в учении. ТС явно новичек и явно учится. Вот пусть и изучает основы, как все это работает.

AF ★★★
( 18.11.15 09:19:06 MSK )
Ответ на: комментарий от Kiborg 17.11.15 17:18:50 MSK

Ты еще волшебный каст с шаблоном предложи 🙂

slackwarrior ★★★★★
( 18.11.15 19:29:33 MSK )
Ответ на: комментарий от slackwarrior 18.11.15 19:29:33 MSK

Я малось нуб в плюсах, можно мне пример, чтоб я тоже шутку понял? 🙂

Kiborg ★★★
( 18.11.15 22:02:16 MSK )
Ответ на: комментарий от Kiborg 18.11.15 22:02:16 MSK

У Саттера были специально расписаны N-способов абузинга прав доступа с целью АЦЦКОГО ХОХОТА к членам класса http://www.gotw.ca/gotw/076.htm чтоб научить всех плохому типа как делать низязя. Еще причудливые люди, узнав про форварды с имплами, любят делать ссылки на экземпляр фасада из импла (потому что отказаться от имплов уже не могут) и прочие атататы 🙂 А потом они открывают для себя Александреску.

slackwarrior ★★★★★
( 18.11.15 23:53:09 MSK )
Ответ на: комментарий от hobbit 17.11.15 20:10:35 MSK

Callback-и в C++ оказываются востребованы либо для связи с «необъектным» кодом, либо при кривой архитектуре.

Совершенно необязательно. Очень часто бывают ситуации, когда сущность определяет, что произошло некоторое событие, но понятия не имеет что с ним дальше делать. В таких случаях удобно делегировать приняние решения какой-нибудь другой сущности (которая не всегда известна первой). Классический пример — кнопка пользовательского интерфейса. Может определить факт того, что ее нажали, но совершенно не знает, как и кто должен обрабатывать это событие. Можно конечно попробовать обмазаться паттерном «наблюдатель» или решать вопрос через наследование, но оба варианта ведут к чудовищной архитектуре. Гораздо правильнее тут использовать какой-нибудь другой callback-механизм (лично мне больше нравися концепция сигналов).

m0rph ★★★★★
( 19.11.15 00:48:11 MSK )
Последнее исправление: m0rph 19.11.15 00:49:15 MSK (всего исправлений: 1)

Как передать класс в функцию c

Привет all!
Такая проблема, имеем класс, одной из функций которого нужно передать параметром тип (конкретно тип класса , но не сам объект), после чего она создает объект этого класса,как это реализовать? За пример буду очень благодарен.
Спасибо.

Re: как передать тип?

От: Андрей Тарасевич
Дата: 31.08.02 04:00
Оценка:

Здравствуйте piAnd, Вы писали:

A>Такая проблема, имеем класс, одной из функций которого нужно передать параметром тип (конкретно тип класса , но не сам объект), после чего она создает объект этого класса,как это реализовать? За пример буду очень благодарен.

class A < public: template class B> B* create() < return new B; > >; . A a; int* pi = a.createint>(); double* pd = a.createdouble>();

Best regards,
Андрей Тарасевич
Re: как передать тип?

От: Рек
Дата: 31.08.02 04:06
Оценка:

Здравствуйте piAnd, Вы писали:

A>Привет all!
A>Такая проблема, имеем класс, одной из функций которого нужно передать параметром тип (конкретно тип класса , но не сам объект), после чего она создает объект этого класса,как это реализовать? За пример буду очень благодарен.
A>Спасибо.

Очень похоже что вместо типа тебе нужно передавать
в функцию фабрику класса.

Примерно чтото такое:

class MyRootObject < >; struct IMyClassFactory < virtual MyRootObject* Create() = 0; >; class A : public MyRootObject < . class ClassFactory : public IMyClassFactory < MyRootObject* Create() < return new A(); > >; static ClassFactory factory; public: static IMyClassFactory* Factory() < return &factory; > >; A::ClassFactory A::factory; class B : public MyRootObject < . class ClassFactory : public IMyClassFactory < MyRootObject* Create() < return new A(); > >; static ClassFactory factory; public: static IMyClassFactory* Factory() < return &factory; > >; B::ClassFactory B::factory; void Do(IMyClassFactory* pFactory) // твоя функция < . MyRootObject* pRoot = pFactory->Create(); . > . Do(A::Factory()); //переадёшь как бы тип. Do(B::Factory()); . Конечно для фабрики классов напрашивается шаблон. 

Re[2]: как передать тип?

От: Рек
Дата: 31.08.02 04:17
Оценка:

Здравствуйте Рек, Вы писали:

Рек>Здравствуйте piAnd, Вы писали:

A>>Привет all!
A>>Такая проблема, имеем класс, одной из функций которого нужно передать параметром тип (конкретно тип класса , но не сам объект), после чего она создает объект этого класса,как это реализовать? За пример буду очень благодарен.
A>>Спасибо.

Рек>Конечно для фабрики классов напрашивается шаблон.

Вот с шаблоном фабрики

class MyRootObject < >; struct IMyClassFactory < virtual MyRootObject* Create() = 0; >; template class T, class C> class MyFactory : public IMyClassFactory < T* Create() < return new C(); > >; /////////////////////////////////// class A : public MyRootObject < static MyFactory factory; public: static IMyClassFactory* Factory() < return &factory; > >; MyFactory A::factory; /////////////////////////////////// class B : public MyRootObject < static MyFactory factory; public: static IMyClassFactory* Factory() < return &factory; > >; MyFactory B::factory; /////////////////////////////////// void Do(IMyClassFactory* pFactory) // твоя функция < MyRootObject* pRoot = pFactory->Create(); > . Do(A::Factory()); //переадёшь как бы тип. Do(B::Factory());

Re: как передать тип?

От: Denwer
Дата: 31.08.02 05:54
Оценка:

Здравствуйте piAnd, Вы писали:

A>Привет all!
A>Такая проблема, имеем класс, одной из функций которого нужно передать параметром тип (конкретно тип класса , но не сам объект), после чего она создает объект этого класса,как это реализовать? За пример буду очень благодарен.
A>Спасибо.

Прочитав другие ответы я все же скажу немного о другом методе решения данной проблемы(обращение к модератору: я читал новые правила, но не удержался от написания ответа в этой теме, хотя надобы его поместить в тему MFC) с использованием MFC, есть там такой класс CRuntimeClass который служит как раз для этой цели, более детально описывать не буду это есть в MSDN.

Re[2]: как передать тип?

От: piAnd
Дата: 01.09.02 17:07
Оценка:

Здравствуйте Все, Вы писали:

Решил остановиться на template.
В связи с возможностью runtime типов(как я понял то,что Вы имели ввиду), для чего это вообще надо? Типы,по-моему все нужны только на этапе компилятора или нетак?

Re[2]: Class Factory

От: aLEXa123
Дата: 01.09.02 19:39
Оценка:

Чрезвычайно интересный пример! А как можно так же красиво реализовать удаление обьекта А?
Вот попробовал, но что-то не получа.

class RootObject<>; struct IFactory < virtual RootObject* Create() = 0; virtual void Destroy() = 0; >; template class T, class C> class Factory : public IFactory < T* Create() < return new C(); > void Destroy()< //delete T; >; >; class A : public RootObject < static Factory factory; public: A()< cout "A created!" static IFactory* Factory() < return &factory; > >; Factory A::factory; //inplements IFactory void Do(IFactory *pIface) < RootObject* pRoot = pIface->Create(); > void Release(IFactory *pIface)< //void (IFactory::*pDestroyFunc)() = &IFactory::Destroy; //pIface->Destroy(); > void main()< IFactory* pfuck = A::Factory(); Do(pfuck); //переадёшь как бы тип. Release(pfuck); >

Re[3]: Class Factory

От: Рек
Дата: 01.09.02 20:09
Оценка:

Здравствуйте aLEXa123, Вы писали:

LEX>А как можно так же красиво реализовать удаление обьекта А?

class MyRootObject < virtual ~MyRootObject() <> // значит деструкторы всех потомков будут виртуальными >; /////////////////////////////////// void Do(IMyClassFactory* pFactory) // твоя функция < MyRootObject* pRoot = pFactory->Create(); . delete pRoot; // вызовется правильный (!) деструктор > . 

Тоже самое надо сделать с фабриками, и ещё их надо не забыть удалить!
я там напартачил:

Do(A::Factory()); так нельзя — фабрика создаётся и не удаляется 8-(

Re[3]: как передать тип?

От: Кодт
Дата: 02.09.02 08:40
Оценка:

Здравствуйте piAnd, Вы писали:

A>Здравствуйте Все, Вы писали:

A>Решил остановиться на template.
A>В связи с возможностью runtime типов(как я понял то,что Вы имели ввиду), для чего это вообще надо? Типы,по-моему все нужны только на этапе компилятора или нетак?

Нет. CRuntimeClass — это MFC-шный класс-хелпер, который умеет идентифицировать и конструировать классы — потомки CObject.

Его преимущество в том, что пользователь имеет дело с интерфейсом базового класса (CObject), а не с самим классом (как в случае шаблона).

И еще одно свойство — идентификация классов по символьным именам (т.е. строкам).

Как передать метод класса в качестве колбэка?

Возможно ли в C++ передавать метод класса в качестве аргумента функции? Как правильно сделать то, что я пытаюсь сделать? (пример сферический в вакууме, поэтому счётчик должен оставаться атрибутом класса)

Всё это нужно для того, чтобы у колбека, передаваемого в качестве аргумента функции независимой библиотеке, оставался доступ к атрибутам объекта.

  • Вопрос задан более трёх лет назад
  • 1413 просмотров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *