Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > С/С++
Перезагрузить страницу Как работать с двумя файлами и двумя функциями
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
dyv dyv вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 25.04.2004
По умолчанию Как работать с двумя файлами и двумя функциями - 25.04.2004, 22:13

в одной функции (1-й файл) я ввожу две строки, надо во второй функции (2-й файл) эти строки вывести
пробовал через extern char *p - линкер плюется в .obj, пишет unresolved extern referenced....

поможите, люди добрые
Ответить с цитированием
  (#2 (permalink)) Старый
Jo Kruger Jo Kruger вне форума
Member
 
Сообщений: 34
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 20.04.2004
По умолчанию Re: 2 файла и 2 функции - 26.04.2004, 19:44

Цитата:
Originally posted by dyv
[b]в одной функции (1-й файл) я ввожу две строки, надо во второй функции (2-й файл) эти строки вывести
пробовал через extern char *p - линкер плюется в .obj, пишет unresolved extern referenced....
поможите, люди добрые
Экстерн надо объявлять в h-нике, например:

foo1.h

Код:
extern char* p;
foo1.cpp

Код:
char *p;

blah-blah-blah.
А в foo2.cpp

Код:
#include "foo1.h"

blah-blah-blah

Но вообщето пользование глобальных переменных - дурной тон. Постарайся выделить обе функции в класс (ведь они у тебя логически связаны) или в крайнем случае делай обмен через синглетон..
Ответить с цитированием
  (#3 (permalink)) Старый
Yttrium Yttrium вне форума
Member
 
Сообщений: 74
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.09.2003
По умолчанию Re: 2 файла и 2 функции - 27.04.2004, 04:14

Цитата:
Originally posted by Jo Kruger
[b]делай обмен через синглетон..
Чё чё
Если можно то в двух словах об этом самом синглетоне.
Ответить с цитированием
  (#4 (permalink)) Старый
dyv dyv вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 25.04.2004
По умолчанию 27.04.2004, 11:46

Спасибо!
Я и делал с хидером.
Вот чуть подробнее. Есть два срр файла. В одном, главном, несколько функций. Я прыгаю между ними. В одной, скажем, f1(), я ввожу две строки, программа их запоминает и показывает юзеру(типа: вы есть Вася Пупкин). Далее я прыгаю во второй срр файл, где одна функция, скажем, f2(). И вот тут мне надо еще раз поприветствовать юзера. Вопрос: как в f2() передать Васю Пупкина? Может, синглетон поможет? Хотя что это - я не знаю.
Ответить с цитированием
  (#5 (permalink)) Старый
Jo Kruger Jo Kruger вне форума
Member
 
Сообщений: 34
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 20.04.2004
По умолчанию Re: 2 файла и 2 функции - 27.04.2004, 11:59

Цитата:
Originally posted by Yttrium+-->
Цитата:
<!--QuoteBegin-Jo Kruger
Цитата:
[b]делай обмен через синглетон..
Чё чё
Если можно то в двух словах об этом самом синглетоне.
Вопервых, как я уже сказал - это на крайний случай, так как пользование синглетона в таком качестве - это по сути те же глобальные переменных, потому как при этом точно также тяжело прослеживается логика работы проги. Правда синглетон при этом имеет некоторые преимущества: вопервых наименование (так как это класс), во вторых освобождение ресурсов по завершении работы проги (т.к. это опятьже класс), в третьих явная инициализация при первом обращении (не будет проблем с неопределенностью в последовательности инициализации глобальных переменных разных модулей), в четвертых не нужно видеть экстерн-объявлений переменных во всех местах использования - видимо будет лишь объявление самого синглетона (иногда это помогает развязать рекурсивные связи между модулями)... ну и так далее. Тоесть, если уж действительно глобальные переменные необходимы, то лучше запользовать синглетон. Но повторюсь, сначала лучше попытаться таки избавиться от глобальных переменных...
У меня на практике лишь один случай пользования глобальных данных. Была некая задачка с исполнением своего скрипта. Вот в ней мне показалось очень удобным завести сингетон с "окружением скрипта", где складировались переменные объявленные внутри скрипта и вспомогательные объекты (типа доступа к внешним устройствам и т.д.). Хотя, здесь можно былоб завести класс Interpretator, который занимался бы исполнением скрипта и внутри которого лежало бы "окружение". Но у меня тогда не предполагалось наличие более чем одного интерпретатора одновременно, потому я и не стал делать класс...
А что касается самого синглетона, то в простейшей реализации - это структура с некими данными, доступ к которой получается через функцию вида:

Код:
SO& getSO()
{
   static SO t;
   return t;
}
Другой вариант, когда эта функция является статической мембер-функцией самого синглетона. В более служных вариантах предусматривается защита от копирования, стратегии выделения и т.д. (смотри библиотеку Loki от Александреску).

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

Вообще, синглетон принято пользовать в случаях, когда в проге появляется некий глобальный ресурс в единичном экземпляре... например клавиатура или саунд, где есть интерфейс для доступа и некие внутренние данные...
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Jo Kruger Jo Kruger вне форума
Member
 
Сообщений: 34
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 20.04.2004
По умолчанию 27.04.2004, 12:07

Цитата:
Originally posted by dyv
[b]Спасибо!
Я и делал с хидером.
Вот чуть подробнее. Есть два срр файла. В одном, главном, несколько функций. Я прыгаю между ними. В одной, скажем, f1(), я ввожу две строки, программа их запоминает и показывает юзеру(типа: вы есть Вася Пупкин). Далее я прыгаю во второй срр файл, где одна функция, скажем, f2(). И вот тут мне надо еще раз поприветствовать юзера. Вопрос: как в f2() передать Васю Пупкина? Может, синглетон поможет? Хотя что это - я не знаю.
Вопервых, если у тебя есть логическая взаимосвязь между f1 и f2 то размести их в классе, имя которого и будет выражать эту связь.. как некий процесс, например аутентификация и т.д. Тогда и с видимостью не будет проблем (все данные будут в этом же классе)..

Другой вариант - заведи класс UserContext, описывающий твоего юзера. Вот в нем и будут эти самые строки. А в функции передавай экземпляр класса, соответствующий конкретному юзеру. В твоем случае f1 может принимать указатель на контекст с целью его уточнения/заполнения, а f2 может принимать константную ссылку на контекст, т.к. она лишь использует его... Вот и всё. Это, видимо и будет верным решением.

А от глобальных переменных откажысь
Ответить с цитированием
  (#7 (permalink)) Старый
Yttrium Yttrium вне форума
Member
 
Сообщений: 74
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.09.2003
По умолчанию 28.04.2004, 04:53

Jo Kruger
шпасибо.
Так вот он какой
Ответить с цитированием
  (#8 (permalink)) Старый
dyv dyv вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 25.04.2004
По умолчанию 14.05.2004, 16:25

Хорошо, я потихоньку учусь, вот немного классы изучил. Но все равно не выходит
Я создал такой класс
Код:
class autentic
{
char name1;
char name2;
public:
void set1(char *S1);
void set2(char *S2);
char get1(void);
char get2(void);
};

void autentic::set1(char *S1)
{
name1 = *S1;
}
void autentic::set2(char *S2)
{
name2 = *S2;
}
char autentic::get1(void)
{
return name1;
}
char autentic::get2(void)
{
return name2;
}
В 1-й функции (она - отдельный файл) все прекрасно. (Не смотрите, что выводит только первые символы, я уже додумался и про вывод строк.) Но ума не приложу, как во 2-й функции (это - другой файл!!!) вызвать из класса нужные данные. Чую, что можно через &, но как? Не выходит. Если писать все в одном файле, то все проходит. но у меня предполагается куча отдельных файлов, где надо не вводить имя, а вызвать уже введенное в главной функции. Поможите юнге!
Код:
int main()
{
char st1[20],st2[30];
cin >> st1;
cin >> st2;
autentic pl1, pl2;
pl1.set1(st1);
pl2.set2(st2);
cout << pl1.get1();
cout << pl2.get2();
}
Ответить с цитированием
  (#9 (permalink)) Старый
Влад Влад вне форума
Специалист
 
Сообщений: 3,884
Сказал(а) спасибо: 1
Поблагодарили 25 раз(а) в 25 сообщениях
Регистрация: 27.06.2002
Адрес: Санкт-Петербург
По умолчанию 14.05.2004, 16:41

Цитата:
Originally posted by dyv
[b]Если писать все в одном файле, то все проходит. но у меня предполагается куча отдельных файлов, где надо не вводить имя, а вызвать уже введенное в главной функции.
Упс! То есть, ты хочешь разделить реализацию функций-членов set1(), set2(), get1(), get2() по разным файлам? Довольно извращенное желание, имхо... Ну ладно, вот рецепт: вынеси объявление класса в *.h -файл (например, autentic.h), а в каждый файл реализации (set1.cpp, set2.cpp, ...) делай #include "autentic.h"
Ответить с цитированием
  (#10 (permalink)) Старый
Anonymous
Guest
 
Сообщений: n/a
По умолчанию 14.05.2004, 23:49

Уж я устал разжевывать. Может, для кого-то это привычные вещи, но пояснить-то можно! Есть два файла, ДВА! В одном (1.срр) функция void vasya(), где чел вводит свое имя и фамилию: вася пупкин. Далее он попадает в ДРУГОЙ ФАЙЛ(2.срр), где только одна функция void vasya2(). И в ней я пишу:
cout << "Hello!";
cout << "Вася Пупкин";
Но я не могу (или не умею) в 2.срр взять строки, введенные в 1.срр!!! Вот проблема! Да, я сделал класс autentic, да я его сделал хидером. Но в 2.срр объявление класса не проходит, идут эрроры. Вот как в 2.срр вывести Вася Пупкин, которые чел ввел в 1.срр? Это реализуемо через класс в хидере? Через амперсанд? Или как? Вещи, кажется, простые для тех, кто уже глубоко сидит в С++.
Спасибо!
Ответить с цитированием
  (#11 (permalink)) Старый
Yttrium Yttrium вне форума
Member
 
Сообщений: 74
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.09.2003
По умолчанию 15.05.2004, 04:04

& амперсанд используют в следующих случаях:
1.Унарная операция взятия адресса
Код:
int i = 5;
int *j = &i;
2. Бинарная логическая побитовая операция И
Код:
f & g;
3. Бинарная логическая операция И
Код:
f && g;
4.Ссылочный тип
Всё больше нет!(не берём во внимание значение перегруженых лексем)

Цитата:
Чую, что можно через &, но как?
а как бы ты хотел его использовать, покажи
Ответить с цитированием
  (#12 (permalink)) Старый
Jo Kruger Jo Kruger вне форума
Member
 
Сообщений: 34
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 20.04.2004
По умолчанию 17.05.2004, 12:16

Цитата:
Originally posted by Anonymous
[b]Уж я устал разжевывать. Может, для кого-то это привычные вещи, но пояснить-то можно! Есть два файла, ДВА! В одном (1.срр) функция void vasya(), где чел вводит свое имя и фамилию: вася пупкин. Далее он попадает в ДРУГОЙ ФАЙЛ(2.срр), где только одна функция void vasya2(). И в ней я пишу:
cout << "Hello!";
cout << "Вася Пупкин";
Но я не могу (или не умею) в 2.срр взять строки, введенные в 1.срр!!! Вот проблема! Да, я сделал класс autentic, да я его сделал хидером. Но в 2.срр объявление класса не проходит, идут эрроры. Вот как в 2.срр вывести Вася Пупкин, которые чел ввел в 1.срр? Это реализуемо через класс в хидере? Через амперсанд? Или как? Вещи, кажется, простые для тех, кто уже глубоко сидит в С++.
Спасибо!
Слушай, ты описываешь решение (идею), а лучшеб привел саму задачу. Потому как то что ты описал уже требует глобальных переменных (в любых проявлениях) - а это в большенстве случаев означает ошибку проектирования.

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

Всё что можно сказать по поводу описанного тобой: Видимо ни функции из 1.cpp и 2.cpp, ни данные (твоя строка) не принадлежат одной сущности. Значит, функция 1, реализующая ввод строки, должна принимать указатель на строку, типа так:
Код:
   void foo1(std::string* str)
   {
      ...
      std::string tmp;
      std::cin>>tmp;
      ...
      *str=tmp;
   }
Можно былоб принять ссылку (проще бцудет тело функции), но указатель лучше, т.к. явно говорит тому кто будет использовать функцию, что функция изменяет аргумент.

Вторая функция просто работает с данным. Значит:

Код:
   void foo2(const std::string& str)
   {
      ....
      например std::cout<<str;
   }

    Ну и тело main может быть таким:

   int main(void)
   {
      std::string suppaName;
      ...
      foo1(&suppaName);
      ...
      foo2(suppaName);
      ...
   }
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как работать с двумя сетевыми картами student1 Сетевые подключения 3 15.06.2012 11:18
Смартфон с двумя SIM-картами SteeKer Выбор телефона 5 24.12.2011 14:07
как работать с двумя винчестерами vierd Любые вопросы от новичков 3 19.10.2011 00:58
как правильно работать с двумя винчестерами vierd Любые вопросы от новичков 7 10.07.2011 17:14
Проблема с двумя DVD Владька Материнские платы 7 19.12.2010 15:16
Работа с двумя приложениями procsi Софт и программы 6 20.10.2008 22:16
Работа с двумя exe файлами Rashad C++ Builder 19 30.01.2006 17:59
Как работать с двумя формами TForm Borislav Delphi 6 12.03.2005 19:47
XSL - работа с двумя XML файлами zoon XML & WML 1 01.12.2004 14:18
Отладка с двумя мониторами Duck Visual C++ 0 16.08.2004 16:05
Как работать с двумя видеокартами одновременно под Dos Anonymous Assembler 1 19.09.2003 17:54
Как map, но с двумя Key imported_Driver С/С++ 8 19.04.2003 14:24



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов