Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.117.183.150] |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Добрый день
Есть два класса работающие вместе общими глобальными переменными. Хочу объединить все вместе в отдельный класс в том числе и переменные. Возникла проблема подклассы не видят у себя внутри этих переменные. Пример. До: int a,b,c,d; - глобальные переменные class Tx; - использует глобальные переменные class Ty; - использует глобальные переменные После: My class { private: int a,b,c,d; public: Tx x; Ty y; } Какие будут идеи? |
Сообщ.
#2
,
|
|
|
Цитата mishapk @ Какие будут идеи? Не видят, потому что они у тебя private. Сделай protected. И, эти глобальные переменные разве не должны быть static? |
Сообщ.
#3
,
|
|
|
Не видят так как подклассы реализуются за пределами класса и они их просто не видят.
Сделал подклассы вложенными, тоже не видят. В Java это вроде возможно а в С++ нет. Остается только через указатели в конструкторе подклассов передавать в виде структуры. Я так думаю. |
Сообщ.
#4
,
|
|
|
Некрасивый вариант:
#include <iostream> using namespace std; class Tx; class Ty; class Config { private: int a = 2, b = 3; friend Tx; friend Ty; }; class Tx { public: int GetA(Config &r) { return r.a; } }; class Ty { public: int GetB(Config &r) { return r.b*2; } }; class Result { public: Config c; Tx x; Ty y; }; int main() { Result R; cout << R.x.GetA(R.c) << endl; cout << R.y.GetB(R.c) << endl; return 0; } |
Сообщ.
#5
,
|
|
|
Цитата mishapk @ Есть два класса работающие вместе общими глобальными переменными. Надо глобальные переменные обернуть классом. Сделать их "public" и "static". Таким образом, любой экземпляр такого класса станет объектом доступа к "глобальным" переменным. |
Сообщ.
#6
,
|
|
|
Ну да, в том числе и для этого придумали синглтоны.
|
Сообщ.
#7
,
|
|
|
Цитата JoeUser @ Ну да, в том числе и для этого придумали синглтоны. Нет, этого не нужно в данном случае. Экземпляров класса может быть любое количество, в этом и удобство. Экземпляр такого класса - это как-бы окошко многоквартирного дома. Каждое из которого выходит на один и тот же двор, и из каждого можно наблюдать одну и ту же картину. И есть возможность кинуть бутылку в одно и то же место. А из той квартиры, где этого окошка нет - дворика не видно. |
Сообщ.
#8
,
|
|
|
Цитата ЫукпШ @ Экземпляров класса может быть любое количество, в этом и удобство. А так неудобно? См Test1Class и Test2Class: #include <iostream> using namespace std; //////////////////////////////////////////////////////////////////////////////////////// template<typename T> struct Holder { Holder() { std::cout << "Holder()::Holder()" << std::endl; if (!Self) Self = new T(); Self->Init(); } ~Holder() { if (Self) { Self->Cleanup(); delete Self; std::cout << "~Holder()::Holder()" << std::endl; } } T* Self = nullptr; }; //////////////////////////////////////////////////////////////////////////////////////// template <typename T> class Singleton { public: static T* Instance() { std::cout << "Singlton::Instance()" << std::endl; static Holder<T> Dummy; return Dummy.Self; } private: Singleton() = delete; Singleton(Singleton const&) = delete; Singleton& operator= (Singleton const&) = delete; Singleton(Singleton const&&) = delete; Singleton& operator= (Singleton const&&) = delete; }; class Global { public: int GetA() { cout << "GetA" << endl; return x-1; } int GetB() { cout << "GetB" << endl; return x+1; } void Init() {}; void Cleanup() {}; private: int x = 1; }; struct Test1Class { void Print() { cout << Singleton<Global>::Instance()->GetA() << endl; } }; struct Test2Class { void Print() { cout << Singleton<Global>::Instance()->GetB() << endl; } }; int main() { Test1Class T1; Test2Class T2; T1.Print(); T2.Print(); return 0; } |
Сообщ.
#9
,
|
|
|
Цитата JoeUser @ Цитата ЫукпШ @ Экземпляров класса может быть любое количество, в этом и удобство. А так неудобно? См Test1Class и Test2Class: Лично мне - нет. Зачем мне дополнительные сущности для достижения той-же цели ? Достаточно описать переменную как "static". |
Сообщ.
#10
,
|
|
|
Цитата ЫукпШ @ Зачем мне дополнительные сущности для достижения той-же цели ? Достаточно описать переменную как "static". В моей реализации переменные получат гарантированно-правильную инициализацию (и освобождение) ресурсов до использования - методы Init и Cleanup. В твоем случае нужно заботиться в предметном коде о недопущении использования до инициализации этих самых бывших "глобальных" переменных нужными значениями, а не полученными по-умолчанию. ИМХО, это аргумент. |
Сообщ.
#11
,
|
|
|
Цитата JoeUser @ private: Singleton() = delete; Singleton(Singleton const&) = delete; Singleton& operator= (Singleton const&) = delete; Singleton(Singleton const&&) = delete; Singleton& operator= (Singleton const&&) = delete; Их нужно в секцию public перенести. Не по феншую, когда удаленные мемберы в закрытой секции. В противном случае ты можешь получить невнятную ошибку компиляции, и сидеть гадать почему так. А вместо класса Holder думаю имеет смысл использовать shared_ptr, или лучше вообще уйти от указателей и возвращать ссылку на статический член класса(Синглтон Майерса.). А то у тебя код для двух статический переменных неоправданно навороченный. Добавлено Цитата JoeUser @ class Global { public: int GetA() { cout << "GetA" << endl; return x-1; } int GetB() { cout << "GetB" << endl; return x+1; } void Init() {}; void Cleanup() {}; private: int x = 1; }; А этот класс я бы вообще выкинул, в нем нет никакого смысла. |
Сообщ.
#12
,
|
|
|
Цитата Wound @ Их нужно в секцию public перенести. Не по феншую, когда удаленные мемберы в закрытой секции. В противном случае ты можешь получить невнятную ошибку компиляции, и сидеть гадать почему так. Возможно. Но лучше поэксперементировать и посмотреть мой вариант и твой. Цитата Wound @ А вместо класса Holder думаю имеет смысл использовать shared_ptr, или лучше вообще уйти от указателей и возвращать ссылку на статический член класса(Синглтон Майерса.). А то у тебя код для двух статический переменных неоправданно навороченный. Давай твой вариант для коллекции |
Сообщ.
#13
,
|
|
|
Цитата JoeUser @ Возможно. Но лучше поэксперементировать и посмотреть мой вариант и твой. В смысле поэкспериментировать? Дело в том, что когда ты пишешь = delete, то компилятор выбрасывает этот член класса. И если вдруг ты его юзнул - тебе он так и скажет, такоой метод помечен как удаленный, так что вызывай другой. А когда ты его делаешь закрытым, то вполне можешь выхватить ошибку аля: не могу вызвать такой метод, он находится в секции private. Когда речь идет о небольшой логике - никаких проблем не будет. Но вдруг если будет что то понавороченее, например с какими нибудь итераторами внутри second/first или еще чего, которые нужно будет куда нибудь перенести или скопировать, то можешь потратить много времени, на выявление ошибок. Цитата JoeUser @ Давай твой вариант для коллекции Тебе какой именно? С Синглтоном? ну хорошо, щас что нибудь напишу. |
Сообщ.
#14
,
|
|
|
Цитата Wound @ А этот класс я бы вообще выкинул, в нем нет никакого смысла. Это класс из которого "фабрика синглтонов" class Singlеton, собственно, и делает синглтон В этом классе и хранятся заветные "глобальные" переменные. Низя это выкидывать. |
Сообщ.
#15
,
|
|
|
А вот интересно, как этот механизм инициализации статических переменных реализуется внутри. Где-то видел в листинге такой вариант - компилятор создает скрытую "совсем-совсем статическую" переменную, которая обнуляется вместе с .bss, после чего при каждом входе в функцию проверяет ее на равенство нулю и, если она ноль, инициализирует явную статическую переменную.
Мое чувство прекрасного сильно страдает от того, что явная переменная фактически дублирует неявную и что все эти действия реально нужны только один раз при запуске программы, но продолжают выполняться и отжирать процессорное время и электричество в течении всего времени выполнения программы. |