Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
1

Указатель на 2 разные вещи..

17.08.2009, 18:41. Просмотров 1182. Ответов 19
Метки нет (Все метки)

Доброго времени суток!
Возникла следующая идея - создается указатель на поток вывода, потом он указывает либо на cout, либо на файл.
Фишка идеи в том, что тогда все функции обращаются к указателю, не зная даже на что он указывает. А то, что они выводят идет либо в cout, либо в файл в зависимости от параметров командной строки(если есть параметр - адрес, то указатель указывает на файл, если параметров нет, то на cout).
Я пытался сделать это так:
C++
1
2
3
4
5
6
7
8
9
10
11
ostream* output;
 
switch(argc)
        {
                case 1:
                        output = &cout;  //указатель на cout
                case 2:
                        {ofstream outfile (argv[1]);
                                if (!outfile) exit(1);
                        output = &outfile;}    //указатель на файл
        }
Но возникли следующие проблемы:
1)Когда outfile исчезает ( область его видимости только {}) и остается только указатель на него, работает ли указатель?
2)В конце надо закрыть файл, а в классе указателя нет close()

Подскажите, как нужно организовать эту идею с указателем.
Заранее спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.08.2009, 18:41
Ответы с готовыми решениями:

Тактовая частота и пропускная способность, это две разные вещи?
У меня вопрос. Тактовая частота и пропускная способность, это две разные вещи?

Как к идентификатору привязать страницу и каждому номеру Id писать разные вещи?
Навеяло отсюда https://www.cyberforum.ru/php-beginners/thread124304.html Все настроил, все...

Произвольное количество потоков синхронизовать так, что бы чётный и нечетный делали разные вещи
Суть в том, что нужно произвольное количество потоков синхронизовать так, что бы чётный и нечетный...

Как сделать так что бы при нажатии одной кнопки сделать разные вещи несколько раз ?
можно взять интегер i, и если оно ровно 1 то делай это а если нет то нет и если кликнуть на кнопку...

19
2807 / 1397 / 107
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 18:55 2
Цитата Сообщение от VorobeY1326 Посмотреть сообщение
1)Когда outfile исчезает ( область его видимости только {}) и остается только указатель на него, работает ли указатель?
указатель работает. но объект локальный - после выполнения блока (аля {}) объект разрушается. тебе надо тогда создавать динамически, чтобы избегнуть этого.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ostream* output;
 
switch(argc)
        {
                case 1:
                        output = &cout;  //указатель на cout
                        break; // это необходимо обязательно!
                case 2:
                        { output = new ofstream(argv[1]);
                                if (!output) exit(1);
                        }
                       break;
        }
 
// и по завершении, не забыть удалить:
delete output;
1
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:09  [ТС] 3
Ладно, с этим разобрался, спасибо.
Теперь осталось понять, как закрывать файл..
Подскажите кто нибудь, плиз!
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 19:10 4
Цитата Сообщение от VorobeY1326 Посмотреть сообщение
Теперь осталось понять, как закрывать файл..
C++
1
outfile.close();
0
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:15  [ТС] 5
Дак в том то и дело, что указатель ostream!! В ostream нет функции close()..
Господа программисты, а если создать указатель ofstream (файловый, где есть и close() и eof()), то такой указатель сможет корректно работать с cout?
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 19:18 6
Цитата Сообщение от VorobeY1326 Посмотреть сообщение
Дак в том то и дело, что указатель ostream!!

C++
1
2
outfile->close();
delete outfile;
0
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
17.08.2009, 19:25 7
Может попробовать,чтобы ostream указывал на ofstream?А если нет то на cout?
1
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:32  [ТС] 8
C++
1
2
3
4
5
6
ostream* output;
 
int main(int argc, char* argv[])
{
     output->close();
}
Выдает ошибку - E2316 'close' is not a member of 'ostream'

Добавлено через 2 минуты 47 секунд
Цитата Сообщение от #pragma Посмотреть сообщение
Может попробовать,чтобы ostream указывал на ofstream?А если нет то на cout?
В том то и дело, что так и есть. Указатель типа ostream указывает либо на ofstream либо на cout. Но при попытке применить к указателю ostream, указывающему на ofstream, close(), компилятор выдает ошибку..
0
2807 / 1397 / 107
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 19:34 9
VorobeY1326, при вызове
C++
1
delete output;
вызовится деструктор.
Если классы писали не индусы, то в деструкторе будет код закрытия потока.
так что, главное удали.

вообще можно вот так:
C++
1
((ofstream*)output)->close();
но мне это не нравится
1
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 19:36 10
Цитата Сообщение от Monte-Cristo Посмотреть сообщение
но мне это не нравится
можно с помощью dynamic_cast определить корректность объекта. но мне это тоже не нравится.
1
2807 / 1397 / 107
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 19:39 11
Цитата Сообщение от zim22 Посмотреть сообщение
можно с помощью dynamic_cast
можно и со static_cast. но от этого смысл не меняется. я лишь показал идею - приведение к типу.
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 19:42 12
VorobeY1326, я понял что ты хочешь сделать.
не лучше ли так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdafx.h"
#include <ostream>
#include <fstream>
#include <iostream>
 
void write(std::ostream &out) {
  out << "yo";
}
 
int _tmain(int argc, _TCHAR* argv[])
{  
  write(std::cout);
  
  std::ofstream out("file.txt");
  write(out);
  out.close();
 
  return 0;
}
Добавлено через 1 минуту 5 секунд
Цитата Сообщение от Monte-Cristo Посмотреть сообщение
можно и со static_cast
нет. нельзя.
static_cast тупо один тип в другой конвертирует.
dynamic_cast следит за корректностью приведения. и в случае, когда приведение к подклассу завершилось неудачей - он либо бросает исключение или возвращает ноль.
0
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:45  [ТС] 13
Спасибо Monte-Cristo, zim22 и #pragma!
Класс действительно писали не индусы..
Я просто в конце удалил output и файл закрылся.
0
2807 / 1397 / 107
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 19:47 14
Цитата Сообщение от zim22 Посмотреть сообщение
нет. нельзя.
C++
1
2
    ostream* output = new ofstream("c:\\tex.txt");
    static_cast<ofstream*>(output)->close();
0
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:47  [ТС] 15
zim22, не, так не лучше..
Потому что идея в том, что указатель может указывать на файл, а может на cout.
То есть данные идут либо в файл, либо в поток вывода.
0
2807 / 1397 / 107
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 20:03 16
VorobeY1326, zim22 тебе показывает вариант тоже с выводом и в файл и в cout. Только через функцию, в которую он перадет по ссылке или std::cout или объект файла. Но в твоем случае, по-моему все равно целесообразней через указатель.

Добавлено через 3 минуты 54 секунды
Цитата Сообщение от zim22 Посмотреть сообщение
нет. нельзя.
Цитата Сообщение от zim22 Посмотреть сообщение
static_cast тупо один тип в другой конвертирует.
dynamic_cast следит за корректностью приведения. и в случае, когда приведение к подклассу завершилось неудачей - он либо бросает исключение или возвращает ноль.
ты сам противоречишь своим словам. в данном случае не рассматривается что лучше, а рассматриваются варианты.
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 20:10 17
Цитата Сообщение от Monte-Cristo Посмотреть сообщение
ты сам противоречишь своим словам.
я не противоречю. для меня "очень плохой подход" и "нельзя" - слова синонимы.

Monte-Cristo, разве ты не понимаешь недостатки static_cast?
сравни это:
C++
1
2
std::ostream* output = 0;
static_cast<std::ofstream*>(output)->close();
с этим:
C++
1
2
3
4
5
6
std::ostream* output = 0;
if (std::ofstream *validPtr = dynamic_cast<std::ofstream*>(output)) {
  do_some_good_things();
} else {
  throw std::bad_cast();
}
0
2807 / 1397 / 107
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 20:22 18
Цитата Сообщение от zim22 Посмотреть сообщение
для меня "очень плохой подход" и "нельзя" - слова синонимы.
ну это каждый сам решает для себя. для меня нет слово нельзя - я поступаю так, как считаю нужным. и это меня не подводило.

Цитата Сообщение от zim22 Посмотреть сообщение
Monte-Cristo, разве ты не понимаешь недостатки static_cast?
я понимаю, недостатки static_cast, но VorobeY1326 интересовался вариантами вызова метода close() класса ofstream.

Это все равно, что если бы он спросил как открыть файл в текстовом режиме через класс ofstream:
я бы ему ответил:
C++
1
ofstream file("somefile.txt");
а не
C++
1
2
3
4
5
ofstream file("somefile.txt");
if (!file) exit(1);
// вот тут используем различные методы для считывания
// или перегруженную операцию >> 
file.close();
Видишь разницу?
Современем, человек сам поймет, как это все работает, и что лучше применять.
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
19.08.2009, 00:07 19
Нужно немного переосмыслить работу.
В начале работы, при некоторых аргументах (условиях), вы создаёте нечто. Следовательно, в конце работы, Вы снова должны будете проверить то же условие, и сообразно ему закрывать или незакрывать поток.

Но это все равно как-то коряво. Может лучше создать на основе std::cout новый объект, дополнив его конструктором и деструктором для проверки параметров.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
10840 / 6671 / 1614
Регистрация: 25.07.2009
Сообщений: 12,440
19.08.2009, 03:51 20
На С я бы примерно так сделал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
 
/* вывод в файл, если указан, или на экран */
 
int main(int argc, char **argv){
    FILE *outfile;
    /*
    Другие объявления...
    */
    
    outfile = ( argc == 2 ) ? fopen(argv[1], "w") : stdout;
    if ( !outfile ) {
        printf("Can't open file for output\n");
        exit(1);
    }
    
    /*
    Собственно программа
    */
    
    if ( outfile != stdout )
        fclose(outfile);
    /* В прочем если в программе перед выходом закрыть stdout, хуже не будет */
    
    exit(0);
}
Примерно такой же подход можно и в С++ применить. Правда, класс создать в С++ - идеологически правильнее, наверное...
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.08.2009, 03:51

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Найти багаж, средний вес одной вещи в котором отличается не более чем на 0.3 кг от общего среднего веса вещи
Задача на файл. Багаж пассажира характеризуеся количеством вещей и общим весом вещей. Дан файл f...

Что такое монитор и что такое мьютекс? Это же разные вещи?
Здравствуйте. В разных айти-статьях по-разному используют эти термины, причём часто их путают друг...

Структура: Найти багаж, средний вес одной вещи, в котором отличается не более чем на 0.3 кг от общего среднего веса одной вещи
Помогите с лабой. За ранее спасибо) Багаж пассажира характеризуется количеством вещей и общим...

Файл: найти багаж, средний вес одной вещи в котором отличается не более чем на m кг от общего среднего веса одной вещи
Нужно написать код к задаче. Кто сможет помогите плиз очень нужно. Заранее спасибо....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.