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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.93
dr.curse
388 / 344 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
#1

Знаю ли я основы ООП? - C++

09.07.2012, 23:11. Просмотров 3802. Ответов 62
Метки нет (Все метки)

ООП я изучал но не применял, ну если не считать собственный класс string и примитивную обертку WinAPI. Так что прошу дайте мне задачи по ООП, чтобы понять на каком уровне находятся мои знания, и на основе этих результатов понять могу ли я читать книгу четырех или еще рано.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.07.2012, 23:11
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Знаю ли я основы ООП? (C++):

Основы ООП - C++
Здраствуйте! Уже второй день пытаюсь разобраться и хорошего ответа так и не нашел. На форуме подобные вопросы видел, и википидею читал, но...

Основы ООП, ввод данных - C++
Собственно, осваивая основы ООП и выполняя заодно частичное задание с универа(1 курс :scratch:) Наткнулся на проблему ввода данных в...

ООП Создание основы класса - C++
Здравствуйте, получил задание, но немного недопонимаю как это сделать, с чего начать. Помогите пожалст или объясните образно как сделать, а...

Ооп. Изучаю основы, обьясните на примере - C++
Класс: форум - сайт для общения. Объект форум - собственно любой форум. Тут все понятно. Форумный движок тоже класс, соответственно...

Основы ООП. Создание стека через класс - C++
Приветствую всех пользователей форума. Относительно недавно начал осваивать ООП. Было необходимо выполнить следующее задание : нужно...

Где могу прочитать про основы ООП? - C++
Где могу прочитать про основы ООП?

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Ksan
27 / 27 / 0
Регистрация: 02.11.2010
Сообщений: 370
10.07.2012, 18:56 #31
aram_gyumri, не загромождать, а делать понятней. Как для разработчика, так и для того, кто будет его кодом пользоваться
0
dr.curse
388 / 344 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
10.07.2012, 18:57  [ТС] #32
Цитата Сообщение от rangerx Посмотреть сообщение
ООП - это методика разработки ПО. Всё, что можно написать с помощью ООП, можно написать и без него(и наоборот). Дело не в самих задачах, а в подходе к решению задач.
я это знаю, просто хотел с помощью задая проверить знаю ли я на достаточном уровне ООП чтобы изучать паттерны

Добавлено через 57 секунд
Цитата Сообщение от Ksan Посмотреть сообщение
aram_gyumri, не загромождать, а делать понятней. Как для разраба, так и для того, кто будет его кодом пользоваться
ну незнаю, помоему функцианальный подход для этой задачи лучше
0
Kastaneda
Форумчанин
Эксперт С++
4653 / 2862 / 228
Регистрация: 12.12.2009
Сообщений: 7,271
Записей в блоге: 2
Завершенные тесты: 1
10.07.2012, 19:13 #33
В этом собственно и соль, решить, казалось бы, чисто "процедурную" задачу при помощи ОО подхода. Решение будет показателем, на сколько ты владешь ООП.
0
dr.curse
388 / 344 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
10.07.2012, 19:19  [ТС] #34
Kastaneda, скажи решение, а то у меня все мысли идут в сторону процедурного решения, или в сторону тупых классов
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.07.2012, 19:28 #35
Kastaneda, Я бы пожалуй сделал простенький аналог boost:rogram_options (совсем простенький, конкретно под данную задачу), соответственно за проверку валидности параметров, может-ли параметр встречаться с другим, является-ли он обязательным (хотя это как раз можно) этот класс не отвечает, он отвечает только за использование допустимых параметров, а дальше можно либо сделать класс который решает задачу, либо сделать три функции, которые собственно будут зваться, зваться будут либо тупо через свитч, либо некая мапа строка -> указатель на функцию.
0
dr.curse
388 / 344 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
10.07.2012, 19:30  [ТС] #36
но все ровно это будет лишь удленнять код
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.07.2012, 20:09 #37
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>
#include <string>
#include <fstream>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
 
namespace po = boost::program_options;
 
namespace params
{
    po::options_description desc;
    std::string file;
    std::string mode;
    std::string word;
}
 
void init_module(int argc, char* argv[])
{
   using namespace params;
   desc.add_options()
      ("help,h", "produce help")
      ("file,f", po::value<std::string>(&file), "input file")
      ("mode,m", po::value<std::string>(&mode), "mode (words, checksum)")
      ("word,v", po::value<std::string>(&word), "work for count (only if mode equal to words")
   ;
   po::variables_map vm;
   po::store(po::parse_command_line(argc, argv, desc), vm);
   po::notify(vm);
   if (vm.count("help"))
   {
       std::cout << desc << std::endl;
       throw std::logic_error("Config error");
   }
   if (!vm.count("file"))
   {
       throw std::logic_error("Config error");
   }
   if (!vm.count("mode"))
   {
       throw std::logic_error("Config error");
   }
   if ((mode == "words" && !vm.count("word")) ||
        (mode == "checksum" && vm.count("word")))
   {
       throw std::logic_error("Config error");
   }
}
 
void count_words(const std::string& file, const std::string& word)
{
    std::ifstream ifs(file.c_str());
    if (!ifs)
    {
        throw std::logic_error("Wrong file");
    }
    const std::string delims = "\n\t,.:!?";
    const std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
    std::vector<std::string> words;
    boost::split(words, content, boost::is_any_of(delims), boost::token_compress_on);
    std::cout << "Word " << word << " contains in file " << std::count(words.begin(), words.end(), word) << std::endl;
}
 
void print_checksum(const std::string& file)
{
    std::ifstream ifs(file.c_str(), std::ios::binary);
    if (!ifs)
    {
        throw std::logic_error("Wrong file");
    }
    int sum = 0;
    while (ifs)
    {
        int value = 0;
        ifs.read(reinterpret_cast<char*>(&value), sizeof(value));
        sum += value;
    }
    std::cout << "Checksum is: " << sum << std::endl;
}
 
int main(int argc, char* argv[])
{
    try
    {
        init_module(argc, argv);
    }
    catch (const std::logic_error& e)
    {
        std::cerr << e.what() << std::endl;
        return 1;
    }
    try
    {
       if (params::mode == "words")
       {
           count_words(params::file, params::word);
       }
       else if (params::mode == "checksum")
       {
           print_checksum(params::file);
       }
       else
       {
           std::cerr << "Wrong argument" << std::endl;
           return 1;
       }
    }
    catch (const std::logic_error& e)
    {
        std::cerr << e.what() << std::endl;
        return 1;
    }
    return 0;
}
Как-нибудь так бы сделал, куда тут совать ООП, кроме парсинга списка аргументов вписаться абсолютно не могу, оно тут просто не нужно, ибо задача одноразовая.
Собственно, Kastaneda, хотелось бы увидеть решение.
0
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
10.07.2012, 20:59 #38
Цитата Сообщение от ForEveR Посмотреть сообщение
... задача одноразовая.
это твое решение - одноразовое. главный смысл ооп не в том, чтобы классов наплодить, а чтобы повторно использовать что-нибудь было удобно. раздели мух и котлеты, потому что в твоем коде нет ни одной детали, которую можно себе представить примененной в другом месте "as is". только в качестве примера и скопипэйстить что-нибудь.
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.07.2012, 21:16 #39
novi4ok, Вообщем-то да, решение одноразовое не спорю, задача здесь абсолютно конкретная, абсолютно конкретно и ее решение, хотелось бы увидеть твой способ решения.
0
Ksan
27 / 27 / 0
Регистрация: 02.11.2010
Сообщений: 370
10.07.2012, 21:37 #40
Вот мое решение


main
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
 
int main()
{
        CLSCommand Command;
        while(1)
        {
                Command.Enter();
        }
        return 0;   
}



CLSCommand
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
class CLSCommand
{
        #define COM_ERROR { cout << "Error\n"; return ; }
        #define VARIANT12 { Variant12(command); return ; }
        #define VARIANT2 { Variant2(filename); return ; }
        #define VARIANT3 { Variant3(command);   return ; }
        public:
                CLSCommand(){   }
                void Enter()
                {
                        char chbuff[64];
                        cout << "me: ";
                        gets(chbuff);
                        Analyse(chbuff);
                }
        private:
                void Analyse(string command) // ïåðâè÷Г*ûé Г*Г*Г*ëèç
                {
                        string strbuff;
                        
                        if(Str2Str(command, 5, strbuff)) COM_ERROR
                        if(strbuff != "test ") COM_ERROR
                        
                        if(Str2Str(command, 2, strbuff)) COM_ERROR
                        if(strbuff == "-f") VARIANT12
                        if(strbuff == "-h") VARIANT3
                        
                        COM_ERROR
                }
                void Variant12(string& command) // Г*Г*Г*ëèç ГўГ*ðèГ*Г*ГІГ* 1, 2
                {
                        string strbuff;
                        if(Str2Str(command, 1, strbuff)) COM_ERROR
                        
                        if(! Validate(command[0], false)) COM_ERROR
                        
                        string filename;
                        for(short i=0; i<command.length(); ++i)
                        {
                                if(! Validate(command[0])) break;
                                filename += command[0];
                                command.erase(0, 1);
                        }
                        
                        if(Str2Str(command, 4, strbuff)) COM_ERROR
                        if(strbuff != " -m ") COM_ERROR
                        
                        strbuff.clear();
                        for(short i=0; i<command.length(); ++i)
                        {
                                if(! Validate(command[0], false)) break;
                                strbuff += command[0];
                                command.erase(0, 1);
                        }
                        
                        if(strbuff == "words")
                        {
                                if(Str2Str(command, 4, strbuff)) COM_ERROR
                                if(strbuff != " -v ") COM_ERROR
                                
                                for(short i=0; i<command.length(); ++i)
                                {
                                        if(! Validate(command[i], false)) COM_ERROR
                                }
                                
                                Variant1(filename, command);
                                
                                return ;
                        }
                        if(strbuff == "checksum") VARIANT2
                        
                        COM_ERROR
                }
                void Variant1(string& path, string& word) // Г*Г*Г*ëèç ГўГ*ðèГ*Г*ГІГ* 1
                {
                        ifstream ifile(path.c_str());
                        int sum = 0;
                        string strbuff;
                        
                        if(! ifile.good()) COM_ERROR
                        
                        while(! ifile.eof())
                        {
                                strbuff.clear();
                                ifile >> strbuff;
                                if(strbuff == word) ++sum;
                        }
                        
                        ifile.close();
                        
                        cout << "sum = " << sum << endl;
                }
                void Variant2(string& path) // Г*Г*Г*ëèç ГўГ*ðèГ*Г*ГІГ* 2
                {
                        ifstream ifile(path.c_str());
                        int sum = 0;
                        char chbuff[5] = "qwer";
                        
                        if(! ifile.good()) COM_ERROR
                        
                        while(! ifile.eof())
                        {
                                ifile.get(chbuff, 4);
                                sum += *(int*)chbuff;
                        }
                        
                        ifile.close();
                        
                        cout << "checksum = " << sum << endl;
                }
                void Variant3(string& command) // Г*Г*Г*ëèç ГўГ*ðèГ*Г*ГІГ* 3
                {
                        if(! command.empty()) COM_ERROR
                        
                        cout << "1) test -f <filename> -m words -v <word>\nprint how many <word> in <filename>\n"
                                 << "2) test -f <filename> -m checksum\nprint 32bit checksum from <filename>\n"
                                 << "3) test -h\nprint help\n";
                }
                
                
                bool Str2Str(string& src, short n, string& dst) // return true if error, else - false
                {
                        dst.clear();
                        if(src.length() < n) return true;
                        
                        for(short i=0; i<n; ++i)
                        {
                                dst += src[i];
                        }
                        src.erase(0, n);
                }
                bool Validate(char ch, bool dota = true)
                {
                        return  (
                                            (ch >= 'a' && ch <= 'z')  ||  
                                            (ch >= 'A' && ch <= 'Z')  ||
                                            (ch >= '0' && ch <= '9')  ||
                                            (ch == '.' && dota)
                                      );
                                
                }
                
        #undef COM_ERROR
        #undef VARIANT12
        #undef VARIANT2
        #undef VARIANT3
};


Добавлено через 23 секунды
Зы: это все было одним файлом. Я разделил для читабельности
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.07.2012, 23:30 #41
novi4ok, Пожалуй я бы внес исправления в свой код, в частности.

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
28
29
30
template<typename CharT, typename TraitsT>
size_t count_words
(
   std::basic_istream<CharT, TraitsT>& stream, const std::basic_string<CharT, TraitsT>& word,
   const std::string& delims
)
{
    size_t count = 0;
    std::basic_string<CharT, TraitsT> str;
    while (std::getline(stream, str))
    {
       std::vector<std::basic_string<CharT, TraitsT>> words;
       boost::split(words, str, boost::is_any_of(delims), boost::token_compress_on);
       count += std::count(words.begin(), words.end(), word);
    }
    return count;
}
 
template<typename CharT, typename TraitsT>
size_t calc_checksum(std::basic_istream<CharT, TraitsT>& stream)
{
    size_t sum = 0;
    while (!stream.eof())
    {
        int current = 0;
        stream.read(reinterpret_cast<char*>(&current), sizeof(current));
        sum += current;
    }
    return sum;
}
Можно пойти к еще большей шаблонизации, чтобы код работал с любым типом потока ввода и любым типом строк.
Так же можно отделить парсинг от подсчета. А во втором как добиться возможности большего повторного использования так сразу на ум не приходит (только если передавать некий функтор который будет считывать нужное кол-во данных, делать какие-то опциональные действия и возвращать кол-во считанных данных). И все же хотелось бы увидеть твой вариант.
1
CyBOSSeR
Эксперт C++
2302 / 1672 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
11.07.2012, 00:49 #42
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от novi4ok Посмотреть сообщение
главный смысл ооп не в том, чтобы классов наплодить, а чтобы повторно использовать что-нибудь было удобно.
Это неверно. БОльшая часть кода любого приложения специфична для задач им решаемым и ни как не предназначена и главное, не подготовлена для повторного использования. А если уж код действительно решает распространенную задачу, то не важно в каком стиле он написан, главное чтобы он был должным образом подготовлен. Вы изучите современные взгляды адекватных адептов ООП, поверьте, о том, что ООП решает задачу повторного использования кода как то лучше других парадигм, Вы не увидите.
4
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
11.07.2012, 01:01 #43
ForEveR, конечно, мы все данный пример рассматриваем как учебный, и нужно не решить, а показать, как мы могли бы решить. в реальной жизни всегда существует еще куча обстоятельств, которые нужно учитывать (что уже имеется, отпущенные время-деньги, какое предполагается развитие и пр.).
с точки зрения ооп (задача поставлена - применить ооп!) в этой задаче я бы выделил "кого-нибудь", кто умеет разбирать параметры и выдать результат (что нужно делать):

инвалидные параметры
посчитать слово "слово"
вычислить контрсумму
вывести подсказку

подсчитывать слова, вычислять сумму и выводить подсказку вроде бы не связанные между собой вещи, и создавать класс, который это все умеет - криво. но и лепить по классу для выполнения каждого из этих заданиц тоже не очень ловко.
но разбираться с ними будет проще, чем с пачкой функций.
твое, ForEveR, решение, тоже - с применением ооп (а что такое stream, vector, boost, как не классы, созданные на базе темплейтов?), но требовалось, наверное, распределить выполнение задания между созданными "самодельными" классами.
я бы такую задачу, если бы мне ее задали на собеседовании, вообще решать не стал. я бы спросил, что они хотят обо мне узнать, пусть спросят, я и так расскажу, без идиотских заморочек.
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
11.07.2012, 01:12 #44
novi4ok, boost это все же namespace. Я просто не стал делать новые классы для разбора и т.д., я показал как сделал бы это при возможности использовать любой готовый код.
0
Kastaneda
Форумчанин
Эксперт С++
4653 / 2862 / 228
Регистрация: 12.12.2009
Сообщений: 7,271
Записей в блоге: 2
Завершенные тесты: 1
11.07.2012, 09:34 #45
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Вобщем я когда-то давно обращался сюда на форум с этой же задачей (и со своим быдлокодом), вот решение, которое предложил CyBOSSeR, на мой взгляд хорошее.
Тут только дизайн, без реализации:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
class Arguments {
public:
  Arguments(char* argv, int arc);
  
  bool        has(char argumentId) const;
  std::string get(char argumentId) const;
};
 
class Command {
public:
  virtual void execute(const Arguments& arguments) const = 0;
};
 
class WordCalculator {
public:
  WordCalculator(const std::string& fileName);
 
  std::size_t calculate(const std::string& word) const;
};
 
class WordCommand : public Command {
public:
  void execute(const Arguments& arguments) {
    WordCalculator calculator(arguments.get('f'));
 
    std::cout << calculator.calculate(arguments.get('v')) << std::endl;
  }
};
 
typedef unsigned int u32;
 
class ChecksumCalculator {
public:
  ChecksumCalculator(const std::string& fileName);
 
  u32 calculate() const;
}
 
class ChecksumCommand : public Command {
public:
  void execute(const Arguments& arguments) {
    ChecksumCalculator calculator(arguments.get('f'));
 
    std::cout << calculator.calculate() << std::endl;
  }
};
 
class HelpCommand : public Command {
public:
  void execute(const Arguments&) {
    std::cout << "bla bla bla" << std::endl;
  }
};
 
class CommandRegistry {
public:
  static void registerCommand(const std::string& commandName, const std::shared_ptr<Command>& command);
  static std::shared_ptr<Command> getCommand(const std::string& commandName);
}
 
void registerCommands() {
  CommandRegistry::registerCommand("word"    , std::make_shared<WordCommand>());
  CommandRegistry::registerCommand("checksum", std::make_shared<ChecksumCommand>());
  CommandRegistry::registerCommand("help"    , std::make_shared<HelpCommand>());
}
 
int main(char* argv, int argc) {
  registerCommands();
 
  Arguments arguments(argv, argc);
 
  const std::string commandName = arguments.has('m')? arguments.get('m') : 'help';
 
  std::shared_ptr<Command> command = CommandRegistry::getCommand(commandName);
 
  command->execute(arguments);
}
3
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.07.2012, 09:34
Привет! Вот еще темы с ответами:

Основы ООП [С++] - C++
Немного знаю Java, написал программу которая по заданным 2-м сторонам и углом между нимию Попробовал перевести на С++ #include &lt;math.h&gt; ...

Классы основы - C++
class a1 // это определение класса { -||-||-; }; a1 b; // как я понимаю это объявление скажите пожалуйста где здесь...

Основы ветвления - C++
Встретился на сайте с такой подачей ветвления: if ( !qwe ) Что значит восклицательный знак, неравенство?

Основы массивов - C++
Изучаю массивы, в книге Объектно-ориентированное программирование в C++ Р. Лафоре. #include &lt;iostream&gt; using namespace std; ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
11.07.2012, 09:34
Ответ Создать тему
Опции темы

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