реклама на сайте
подробности

 
 
> Доступ к методам (функциям) класса., Выбор оптимального способа
Stas633
сообщение Oct 13 2008, 21:44
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901



Допустим:
- имеются два класса TOne и TTwo;
- в TOne определена ф-ция FuncOne();
- классы определены в разных единицах компиляции (файлах);
- созданы объекты (глобальные) этих классов (mOne и mTwo) в третьем файле - "main.cpp".
Вопрос:
Как из класса TTwo получить доступ (использовать) функцию FuncOne() класса TOne?

1. наследовать TOne в TTwo
2. перед описанием класса TTwo объявить объект классаа TOne: extern TOne mOne.
3. ...?
...
А если таких "вложений" больше? (Т.е. функции TTwo, использующие TOne, необходимы в TThree)

Что лучше? Как правильнее? Есть ли разница в испозовании стека?

Прим. Например: TOne - класс описывающий работу с индикатором (LCD), а TTwo - класс формирования данных для вывода на индикатор. Рассматривается ситуация одного процесса (не RTOS).

Прим.1 Вопрос задаю здесь, так как обсуждение темы о выделении раздела форума для "чистого" программирования, увы, ни к чему не привело. smile.gif Господа Админы/Модераторы извините, просмотрел..
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
dxp
сообщение Oct 14 2008, 08:12
Сообщение #2


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Stas633 @ Oct 14 2008, 04:44) *
Что лучше? Как правильнее? Есть ли разница в испозовании стека?

Прим. Например: TOne - класс описывающий работу с индикатором (LCD), а TTwo - класс формирования данных для вывода на индикатор. Рассматривается ситуация одного процесса (не RTOS).

Что лучше и правильнее, зависит от задачи. Если один класс является другим + некоторые свои расширения, то имеет смысл наследовать, если один класс содержит функциональность другого, то имеет смысл включить один в другой. Если классы живут сами по себе, то ничего вышесказанного делать не нужно, а общение меж ними организовать на открытой части (public). Для того, чтобы сделать объект глобальным (не важно, какой объект - класса или встроенного типа), нужно объявить объект в одном из исходных файлов, а в одном из заголовочных, который включается во все исходные, объявить этот же объект с квалификатором extern. Тогда объект будет виден и доступен везде, где есть это объявление.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Stas633
сообщение Oct 14 2008, 20:58
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901



bb-offtopic.gif
Ув. dxp, спасибо за Ваши советы/рекомендации (в другой ветке)!!!
... При внешней схожести С и С++ очень разные языки... ...разные тем, что на них думать надо совсем по-разному... ...
Попробуйте думать над программой на уровне объектов реального мира, ..., тогда реализация ляжет на классы почти сама собой... (с) dxp

Начал ознакомление с работами Страуструпа и Буча ("настольной книгой", до последнего времени, был "Самоучитель..." Шилдта) и сразу понял, что, используя синтаксис и правила С++, пишу на Си! Отсюда и "проблемы" вида: ".. как сделать функцию доступной.." и т.д.
При написании программы я использовал "прямое" наследование для получения доступа к функциям базовых классов. Т.е. при создании объекта производного класса создавался объект/копия базового класса и таких копий было "множество", хотя достаточно одной единственной. Последствия, в виде "нехватки" ОЗУ, очевидны... Отсюда и мой интерес к получению "беззатратного" доступа к "чужим" функциям.
Программу нужно писать на С++, а не на Си, изпользуя С++ синтатсис и правила!! smile.gif Т.е. начинать нужно с рисования структуры связей и т.д.
Спасибо еще раз! a14.gif

Цитата(dxp @ Oct 14 2008, 12:12) *
... Если классы живут сами по себе, то ничего вышесказанного делать не нужно, а общение меж ними организовать на открытой части (public)....

Что Вы имеете ввиду? Если не через наследование, то как тогда?
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 15 2008, 04:32
Сообщение #4


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Stas633 @ Oct 15 2008, 03:58) *
Что Вы имеете ввиду? Если не через наследование, то как тогда?

Не очень понимаю затруднение. Вот имеем код:

Код
class TSlon
{
public:
    TSlon();
    void f();
};

class TMamont
{
public:
    TMamont();
    void f();
};
...

TSlon slon;
TMamont mamont;

void TMamont::f()
{
    slon.f();
}


как видно, спокойно вызываем из функции одного класса функцию другого. Все public члены классов доступны внешнему окружению без каких-либо ограничений. Это так задумано, и это логично. Управление доступом - основа инкапсуляции/абстракции. Представление прячем в private секцию объекта, а общение (функциональность) делаем через интерфейс - public секцию. Как правило, в public секции присутствуют только функции. Т.е. интерфейс - это действия, которые может выполнять объект, а доступ к данным снаружи как правило не нужен и чреват хаками и ошибками. Хотя, конечно, язык не запрещает делать открытыми и данные-члены.

В некоторых случаях возникает необходимость дать доступ к закрытой части одного класса другому классу, но при это не хочется делать эту часть открытой, чтобы к ней не было доступа всем. В этом случае можно объявить класс, который нуждается в доступе, как friend (друг) в классе, к представлению которого требуется доступ.

Или вам что-то другое надо?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Stas633
сообщение Oct 15 2008, 08:09
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901



Цитата(dxp @ Oct 15 2008, 08:32) *
Или вам что-то другое надо?

Нет, "другого" не нужно. Вопрос в разной терминологии. Вы это называете "...общение ... на открытой части...", а я называл "..объявлением объекта перед использованием класса". Ваша терминология конечно правиль-на (-нee). Вообще, "одинаковый алфавит" - это начало начал при обсуждении любого вопроса.
В предложенном варианте необходимо "помнить" (держать в памяти) где и с каким именем объявлен объект slon. Если он объявлен в main - файле, то в в файле описания TMamont нужно этот обект объявлять как extern и т.д. Т.е. опять "возврат" к Си.
bb-offtopic.gif
По "точный" ответ на "точный" вопрос вспомнился старый анекдот... Когда воздухоплаватель на воздушном шаре приземлился в незнакомой местности и спросил у проходившего мимо программиста: "Где я нахожусь?". И тот, после недолгого раздумья, ответил: "Вы находитесь в корзине воздушного шара." Ответ правильный и точный но... smile.gif
(не примите, плз., это на свой счет, это так, к слову).
...
Правильнее, на мой "просветленный" smile.gif взгляд, построить "объектную модель программы" и создать иерархию классов с использованием абстактных классов (гл.12, "Язык программирования C++", Б.Страуструп). Хотя для Си - программиста это и покажется более сложным. Кстати, предложенную Вами реализацию меню через наследование абстактного класса успешно реализовал, правда, как оказалось, не понимая сути smile.gif


Цитата(alexander55 @ Oct 15 2008, 09:19) *
Тут надо смотреть, как правильнее по смыслу.
...
Хорошо об этих проблемах написано в книге ""Философия Java".

Вы правы - "Философия...". smile.gif Т.е. нужно менять подход, а не искать "средства".
В общем-то, вопрос о способах доступа раскрыт, как мне кажется, полностью.
Главный вывод это то, что нельзя (неправильно, трудно, неэффективно...) использовать объекты для описания процедур.
Нужно или "заниматься" (программировать) обектно ориентированным программированием, или процедурным. Написана программа на Си - нет смысла пытаться "подогнать" ее под С++. А вот использовать готовые куски кода (функции) - пожалуйста.
Спасибо!

P.S. Способов два:
- через наследование. НО! Если базовые классы не являются абстрактными, но наследование приводит к избыточному наличию копий базовых классов (обектов) (если не прав - поправьте);
- через указатель на класс (объект). НО! Здесь проявляется вся "прелесть" продердурного программирования и смысл перехода от Си к С++ теряется.
... предложенное dxp "включить один (класс) в другой" не рассматриваю, так как производных классов несколько, и включение базового в каждый .............

Вместе с тем, любой из вариантов работоспособен и не является ошибочным. И, в зависимости от ситуации, может быть применен.
Go to the top of the page
 
+Quote Post
dxp
сообщение Oct 15 2008, 11:59
Сообщение #6


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Stas633 @ Oct 15 2008, 15:09) *
В предложенном варианте необходимо "помнить" (держать в памяти) где и с каким именем объявлен объект slon. Если он объявлен в main - файле, то в в файле описания TMamont нужно этот обект объявлять как extern и т.д. Т.е. опять "возврат" к Си.

Никакого возврата нет, т.к. С++ - это надмножество С, и использует те же средства в полном объеме. Помнить, под каким именем объявлен объект slon не надо - он объявлен под именем slon. smile.gif Для организации доступа к глобальному объекту нужно (в данном случае):
  1. Определения классов поместить в заголовочный файл, который включается во все исходные файлы проекта.
  2. В одном из исходных файлов объявить сами объекты.
  3. В вышеуказанном заголовочном файле поместить следующие объявления:
    extern TSlon slon;
    extern TMamon mamont;
Все, теперь оба объекта будут доступны везде. Если надо доступ к потрохам, об этом уже сказано выше.

Цитата(IgorKossak @ Oct 15 2008, 15:38) *
Никто почему-то не сказал о средстве friend.
Т. е. в классе TTwo обьявить другом класс TOne.

Почему не сказал? Было предложено. smile.gif

Цитата(Stas633 @ Oct 15 2008, 18:18) *
А чем наследование лучше/хуже доступа через friend? (для рассматриваемого случая)

Оно не лучше и не хуже. Это просто другое. Никто, кроме вас, не знает, как лучше написать вашу программу. Про отношения объектов в программе можно привести такую аналогию. Например, имеем объеты "слон" и "мамонт". Мамонт является разновидностью слона - у него есть все, что есть у слона (хобот, хвост, четыре ноги, голова, туловище, и по габаритом тоже похож), но кроме того мамонт еще имеет кое-что свое - бивни загнутые, густую шерсть и т.д. В этой ситуации, если есть описание слона, логично мамонта делать не с нуля, а на базе имеющегося описания слона - т.е. отнаследоваться от слона и добавить недостающие особенности. Преимещества такого подхода в том, что, во-первых, писанины меньше, во-вторых, если надо что-то общее поменять в обоих зверях, то сделать это можно просто и без ошибок, модифицируя только описание слона. Ну, и плюс возможности гибкого управления функциональностью потомков через полиморфизм. Это описано отношение наследования.

Далее. Допустим есть объекты "слон", "мамонт" и "стадо". Поскольку стадо состоит из животных, то логично, чтобы объект "стадо" включал в себя объекты слонов и мамонтов (возможно, в виде массивов). Это отношение включения.

Ну, и наконец, пусть есть объекты "слон" и "бегемот". Тут ни один из другого не получается и ни один другого включать не может (если только не сожрет smile.gif ). Но взаимоотношения между ними строить можно (например, один прогнал другого с пастбища или еще что-то, я не знаток зоологии smile.gif ). В этом случае это просто отдельные независимые объекты, которые живут сами по себе, но могут пользоваться открытыми функциями-членами друг друга, как я приводил выше. Можно даже закрытыми, если один объявить другом другого (хотя с трудом представляю себе такую дружбу в натуре smile.gif ). Однозначно имеет смысл тут завести абстрактный базовый класс Animal (с виртуальной функций eat smile.gif ), и от него наследовать обоих зверушек. Это уже позволит их обоих накормить единоорабазно в цикле. smile.gif

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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
?ELF
сообщение Oct 17 2008, 20:18
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 163
Регистрация: 8-09-06
Из: Россия, Челябинская область
Пользователь №: 20 187



Цитата(dxp @ Oct 15 2008, 17:59) *
...
...
...

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

Спасибо! a14.gif
Хорошая аллегория.
Прочитал Ваш ответ -- словно "в юности побывал" -- "Страуструпп Б. - Язык программирования С++., Диасофт, Киев, 1993."

---
Вообще, такие вещи, на мой взгляд, более логично и более глубоко описывались в Prolog-е.
Создал "базу знаний" -- и вперёд!
Используй термы, предложения, правила, предикаты...
Почти умер язык, к сожалению.
Не выдержал коммерческого натиска C++.


--------------------
do ut des
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Stas633   Доступ к методам (функциям) класса.   Oct 13 2008, 21:44
- - igorenja   Цитата(Stas633 @ Oct 14 2008, 03:44) Я ...   Oct 14 2008, 05:19
|- - Stas633   Цитата(dxp @ Oct 15 2008, 15:59) Словом, ...   Oct 15 2008, 12:22
|- - IgorKossak   Цитата(dxp @ Oct 15 2008, 14:59) Почему н...   Oct 15 2008, 16:10
- - alexander55   Цитата(Stas633 @ Oct 14 2008, 01:44) Ту...   Oct 15 2008, 05:19
- - IgorKossak   Цитата(Stas633 @ Oct 14 2008, 00:44) Вопр...   Oct 15 2008, 08:38
- - vik0   Вставлю и я свои 5 копеек 1. Если у Вас TOne - та...   Oct 15 2008, 09:39
- - Stas633   Чтобы не было "гаданий на кофейной гуще...   Oct 15 2008, 11:18
- - bookevg   Цитата(Stas633 @ Oct 15 2008, 14:18) Чтоб...   Nov 6 2008, 12:45
- - Stas633   Цитата(bookevg @ Nov 6 2008, 15:45) ... С...   Nov 7 2008, 07:25
- - Stas633   Поиск "оптимального" решения продолжаетс...   Nov 21 2008, 20:03
- - bookevg   Цитата(Stas633 @ Nov 21 2008, 23:03) Поис...   Nov 22 2008, 08:28
- - Stas633   Цитата(bookevg @ Nov 22 2008, 11:28) Я та...   Nov 22 2008, 10:09
- - bookevg   Цитата(Stas633 @ Nov 22 2008, 13:09) Сове...   Nov 24 2008, 13:51
- - Stas633   Ув. bookevg, Вы, безусловно, во многом правы! ...   Nov 24 2008, 22:08


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 18:48
Рейтинг@Mail.ru


Страница сгенерированна за 0.01764 секунд с 7
ELECTRONIX ©2004-2016