Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
VorobeY1326
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
#1

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

17.08.2009, 18:41. Просмотров 941. Ответов 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()

Подскажите, как нужно организовать эту идею с указателем.
Заранее спасибо!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.08.2009, 18:41     Указатель на 2 разные вещи..
Посмотрите здесь:

Как реализовать указатель "n" размерности на разные объекты? - C++
Подскажите как реализовать следующее: //есть базовый класс у которого куча производных классов с перегруженными вируальными функциями....

Как переопределить функцию так, чтобы она не только могла принимать разные параметры, но и возвращать тоже разные? - C++
То есть я считаю несправедливым, если такое проканывает: void f () {;} void f (int) {;} а такое нет: void f (int) {;} int f...

указатель на указатель или присваивание объекта - C++
Доброе утро. Вот я в своем классе создал параметр class TTo4ka { ... TGrup **MyGrup; ... };

Указатель на указатель и Нарушение прав доступа - C++
функция, добавляющая новый элемент в динамический массив из указателей При вызове : pData=Add(NULL,1,question); Работает исправно,...

Зачем использовать Указатель на указатель? - C++
Подскажите зачем использовать Указатель на указатель? И как работают двумерные массивы за счет указателей?

Задача на указатели.Указатель на указатель. - C++
Таблица футбольного чемпионата задана квадратной матрицей порядка n, в которой все элементы, принадлежащие главной диагонали равны 0, а...

Указатель на указатель заполнение матрицы - C++
Помогите как самому вбивать матрицу скоко на скоко и элементы этой матрицы ( без функций ) используя только <iostream>. (помощь)

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Monte-Cristo
2787 / 1373 / 30
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 18:55     Указатель на 2 разные вещи.. #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;
VorobeY1326
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:09  [ТС]     Указатель на 2 разные вещи.. #3
Ладно, с этим разобрался, спасибо.
Теперь осталось понять, как закрывать файл..
Подскажите кто нибудь, плиз!
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 19:10     Указатель на 2 разные вещи.. #4
Цитата Сообщение от VorobeY1326 Посмотреть сообщение
Теперь осталось понять, как закрывать файл..
C++
1
outfile.close();
VorobeY1326
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:15  [ТС]     Указатель на 2 разные вещи.. #5
Дак в том то и дело, что указатель ostream!! В ostream нет функции close()..
Господа программисты, а если создать указатель ofstream (файловый, где есть и close() и eof()), то такой указатель сможет корректно работать с cout?
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 19:18     Указатель на 2 разные вещи.. #6
Цитата Сообщение от VorobeY1326 Посмотреть сообщение
Дак в том то и дело, что указатель ostream!!

C++
1
2
outfile->close();
delete outfile;
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
17.08.2009, 19:25     Указатель на 2 разные вещи.. #7
Может попробовать,чтобы ostream указывал на ofstream?А если нет то на cout?
VorobeY1326
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:32  [ТС]     Указатель на 2 разные вещи.. #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(), компилятор выдает ошибку..
Monte-Cristo
2787 / 1373 / 30
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 19:34     Указатель на 2 разные вещи.. #9
VorobeY1326, при вызове
C++
1
delete output;
вызовится деструктор.
Если классы писали не индусы, то в деструкторе будет код закрытия потока.
так что, главное удали.

вообще можно вот так:
C++
1
((ofstream*)output)->close();
но мне это не нравится
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 19:36     Указатель на 2 разные вещи.. #10
Цитата Сообщение от Monte-Cristo Посмотреть сообщение
но мне это не нравится
можно с помощью dynamic_cast определить корректность объекта. но мне это тоже не нравится.
Monte-Cristo
2787 / 1373 / 30
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 19:39     Указатель на 2 разные вещи.. #11
Цитата Сообщение от zim22 Посмотреть сообщение
можно с помощью dynamic_cast
можно и со static_cast. но от этого смысл не меняется. я лишь показал идею - приведение к типу.
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 19:42     Указатель на 2 разные вещи.. #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 следит за корректностью приведения. и в случае, когда приведение к подклассу завершилось неудачей - он либо бросает исключение или возвращает ноль.
VorobeY1326
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:45  [ТС]     Указатель на 2 разные вещи.. #13
Спасибо Monte-Cristo, zim22 и #pragma!
Класс действительно писали не индусы..
Я просто в конце удалил output и файл закрылся.
Monte-Cristo
2787 / 1373 / 30
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 19:47     Указатель на 2 разные вещи.. #14
Цитата Сообщение от zim22 Посмотреть сообщение
нет. нельзя.
C++
1
2
    ostream* output = new ofstream("c:\\tex.txt");
    static_cast<ofstream*>(output)->close();
VorobeY1326
Ученик 11 класса)
4 / 4 / 0
Регистрация: 11.04.2009
Сообщений: 67
17.08.2009, 19:47  [ТС]     Указатель на 2 разные вещи.. #15
zim22, не, так не лучше..
Потому что идея в том, что указатель может указывать на файл, а может на cout.
То есть данные идут либо в файл, либо в поток вывода.
Monte-Cristo
2787 / 1373 / 30
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 20:03     Указатель на 2 разные вещи.. #16
VorobeY1326, zim22 тебе показывает вариант тоже с выводом и в файл и в cout. Только через функцию, в которую он перадет по ссылке или std::cout или объект файла. Но в твоем случае, по-моему все равно целесообразней через указатель.

Добавлено через 3 минуты 54 секунды
Цитата Сообщение от zim22 Посмотреть сообщение
нет. нельзя.
Цитата Сообщение от zim22 Посмотреть сообщение
static_cast тупо один тип в другой конвертирует.
dynamic_cast следит за корректностью приведения. и в случае, когда приведение к подклассу завершилось неудачей - он либо бросает исключение или возвращает ноль.
ты сам противоречишь своим словам. в данном случае не рассматривается что лучше, а рассматриваются варианты.
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
17.08.2009, 20:10     Указатель на 2 разные вещи.. #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();
}
Monte-Cristo
2787 / 1373 / 30
Регистрация: 07.03.2009
Сообщений: 4,446
17.08.2009, 20:22     Указатель на 2 разные вещи.. #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();
Видишь разницу?
Современем, человек сам поймет, как это все работает, и что лучше применять.
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
19.08.2009, 00:07     Указатель на 2 разные вещи.. #19
Нужно немного переосмыслить работу.
В начале работы, при некоторых аргументах (условиях), вы создаёте нечто. Следовательно, в конце работы, Вы снова должны будете проверить то же условие, и сообразно ему закрывать или незакрывать поток.

Но это все равно как-то коряво. Может лучше создать на основе std::cout новый объект, дополнив его конструктором и деструктором для проверки параметров.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.08.2009, 03:51     Указатель на 2 разные вещи..
Еще ссылки по теме:

Указатель на функцию возвращающую указатель - C++
Всем привет. Подскажите, пожалуйста, пример не очень сложной программы, в которой встречается указатель на функцию, принимающую параметр...

Указатель на указатель внутри структуры - C++
Приветствую. Есть 2 структуры: enum category { Technical, History, Fiction }; struct BOOK { char author; char name; int...

Сделать указатель на указатель NULL - C++
есть код: class Matrix { private: double **data; //нужно, чтобы в самом начале это было NULL double *b; //и это тоже было NULL ...

Динамический массив и указатель на указатель - C++
Спасибо за внимание) Задача такова: нужно удалить элемент по индексу, при этом уменьшить сам массив на 1 (т.е. удалили элемент - уменьшился...

Указатель на указатель - разница способов - C++
int a =5; int *b = &amp;a; int **e =&amp;b; //первый способ //Нужно писать столько * скока указателей.. int *f = b; //Втрой...


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

Или воспользуйтесь поиском по форуму:
easybudda
Эксперт С++
9456 / 5469 / 927
Регистрация: 25.07.2009
Сообщений: 10,495
19.08.2009, 03:51     Указатель на 2 разные вещи.. #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);
}
Примерно такой же подход можно и в С++ применить. Правда, класс создать в С++ - идеологически правильнее, наверное...
Yandex
Объявления
19.08.2009, 03:51     Указатель на 2 разные вещи..
Ответ Создать тему
Опции темы

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