Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
0 / 0 / 0
Регистрация: 10.07.2014
Сообщений: 13
1

Какие ошибки допущены при проектировании класса

27.07.2014, 12:36. Показов 1754. Ответов 29
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите пожалуйста, какие ошибки допущены при проектировании класса, если они имеются:

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
#include "stdafx.h"
#include <fstream>
 
class FileClient
{
protected:
    char* p;
public:
 
    virtual void connect() = 0;
    void close(){}
    virtual void ping()
    {
        printf("%s : %s", "__FUNCTION__", p);
    }
    FileClient()
    {
        p = new char[10];
        p[0] = '1';
    }
    ~FileClient()
    {
        delete p;
    }
};
class Client : public FileClient
{
    FILE* hFile;
public:
    virtual void connect()
    {
        hFile = fopen("d:\test.txt", "w");
    }
    void ping()
    {
        char arr[] = { 0, 0, 5, 56, 12, 32 };
        fwrite(arr, 1, sizeof(arr), hFile);
        FileClient::ping();
    }
    ~Client()
    {
        delete[] p;
        p = 0;
    }
};
 
int main()
{
    FileClient* client = new Client;
    client->connect();
    client->ping();
    delete client;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.07.2014, 12:36
Ответы с готовыми решениями:

Использование конструкторов и деструктора при проектировании пользовательского класса
Дан одномерный массив A. Найти max (a2, a4, …, a2k) + min (a1, a3, …, a2k+1).

Ошибки при наследовании класса
Доброго времени суток!Возникли ошибки при компиляции кода Задание было такое:Создать абстрактный...

Ошибки при перегрузке операторов класса
Задали в универе для класа триугольника с полями 3х сторон реализовать перегрузку операторов &lt;&lt;,...

Ошибки при наследовании класса от вектора
Пишу программу по СМО, столкнулся с трудностью при попытке сделать наследование очередью Cqueue...

29
Модератор
Эксперт С++
13507 / 10757 / 6412
Регистрация: 18.12.2011
Сообщений: 28,712
27.07.2014, 12:52 2
C++
1
2
3
4
5
6
7
8
9
10
FileClient()
    {
        p = new char[10];
        p[0] = '1';
        p[1]=0; // строка должна заканчиваться терминальным нулем
    }
    ~FileClient()
    {
        delete[]  p; // удаляется массив
    }
Добавлено через 2 минуты
C++
1
2
3
4
5
~Client()
    {
       ~FileClient();
    }
Client():FileClient(){}
0
0 / 0 / 0
Регистрация: 10.07.2014
Сообщений: 13
27.07.2014, 13:05  [ТС] 3
спасибо, но еще отказывается компилиться строка:
C++
1
    hFile = fopen("d:\test2.txt", "w");
#include <stdio.h> добавлено
0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
27.07.2014, 13:30 4
trev, обратный слэш надо экранировать
C++
1
"d:\\test2.txt"
либо используй прямой
C++
1
"d:/test2.txt"
Добавлено через 9 минут
Цитата Сообщение от trev Посмотреть сообщение
#include <stdio.h> добавлено
C++
1
2
3
4
5
#include <cstdio>
 
// ...
 
hFile = std::fopen("d:/test2.txt", "w");
Добавлено через 2 минуты
+ файл не закрывается.
0
0 / 0 / 0
Регистрация: 10.07.2014
Сообщений: 13
27.07.2014, 13:54  [ТС] 5
так.. вроде все работает, но почему то этот фрагмент:
C++
1
2
3
4
5
6
void ping()
    {
        char arr[] = { '0', '0', '5', '56', '12', '32' };
        fwrite(arr, 1, sizeof(arr), hFile);
        FileClient::ping();
    }
не выводит двузначные символы как надо, например вместо "56" он записывает в файл 6, "12" = "2" и так далее..
0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
27.07.2014, 14:32 6
trev, char хранит один символ, 56 - это два символа.
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
27.07.2014, 14:47 7
trev, потому что multi-character character constant имеет тип int, а не char. Лучше так вообще не делать. Ибо непереносимо, и даже здесь (в таком простейшем случае) проявляются всякие побочные эффекты.

Добавлено через 28 секунд
Цитата Сообщение от gray_fox Посмотреть сообщение
вообще запись вроде '56' некорректна
Корректна, но непереносима. Это multi-character character constant.

Добавлено через 10 минут
Цитата Сообщение от trev Посмотреть сообщение
не выводит двузначные символы как надо, например вместо "56" он записывает в файл 6, "12" = "2" и так далее..
Внутреннее устройство multi-character character constant может отличаться от компилятора к компилятору. Но здесь, видимо, происходит следующее:
C++
1
2
3
4
5
6
7
8
9
int main()
{
    int b = '12';
// запись мультисимвола '12' в little-endian
//    *((char*)&b)       = '2';
//    *(((char*)&b) + 1) = '1';
 
    char c = (char)b; //получаем 2
}
Добавлено через 3 минуты
trev, вот тут еще почитай.
1
Заблокирован
Автор FAQ
27.07.2014, 14:52 8
Цитата Сообщение от trev Посмотреть сообщение
FILE* hFile;
- почему не обнуляем?
Цитата Сообщение от trev Посмотреть сообщение
~Client()
* * {
* * * * delete[] p;
* * * * p = 0;
* * }
- почему не закрываем возможно открытый файловый поток?
Цитата Сообщение от trev Посмотреть сообщение
hFile = fopen("d:\test2.txt", "w");
- если в проекте в настрйоках юникод то
C++
1
hFile = fopen(L"D:\\test2.txt", L"w");
если проект без юникода, то hFile = fopen("D:\\test2.txt", "w");
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
#include <fstream>
#include <cstdio>
using namespace std;
 
class FileClient
{
protected:
    char* p;
public:
 
    virtual void connect() = 0;
    void close(){}
    virtual void ping()
    {
        printf("%s : %s", "__FUNCTION__", p);
    }
    FileClient()
    {
        p = new char[10];
        p[0] = '1';
    }
    ~FileClient()
    {
        delete p;
    }
};
class Client : public FileClient
{
    FILE* hFile;
public:
    Client() : hFile( NULL ) {}//кто обнулять будет?
    virtual void connect(){
        //глупая функция путь к файлу и параметры следует передават ьв функцию а не забивать
        hFile = fopen("D:\\test.txt", "w");
    }
    void ping()
    {
        char arr[] = { 0, 0, 5, 56, 12, 32 };
        fwrite(arr, 1, sizeof(arr), hFile);
        FileClient::ping();
    }
    ~Client()
    {
        if( p )
        delete[] p;
        p = 0;
        if( hFile )
            fclose(hFile);
    }
};
 
int main()
{
    FileClient* client = new Client;
    client->connect();
    client->ping();
    delete client;
}
http://codepad.org/HWxjYvDk
Самой большой глупостью считаю использование потока из stdio к чему вообще fstream?
0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
27.07.2014, 14:55 9
Кстати, деструктор то в FileClient должен быть виртуальным.
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
27.07.2014, 15:04 10
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
if( p ) delete[] p;
На ноль не нужно проверять перед delete. Для delete гарантировано стандартом корректное поведение при передаче ему нуля.
0
Заблокирован
Автор FAQ
27.07.2014, 15:09 11
Цитата Сообщение от DrOffset Посмотреть сообщение
На ноль не нужно проверять перед delete. Для delete гарантировано стандартом корректное поведение при передаче ему нуля.
- а если передали битый поинтер + ещё линкер с отклонением от стандарта (скажем студийный, который сгененрирует исключение)?
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
27.07.2014, 15:14 12
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
а если передали битый поинтер + ещё линкер с отклонением от стандарта
Как проверка на ноль может вычислить битый пойнтер? И при чем тут линкер?
Вот этой проверкой:
C++
1
2
if(p)
   delete [] p;
ты ничего кроме нуля в p не отдетектишь, однако стандартом гарантируется что вот такая запись корректна
C++
1
2
p = 0;
delete[] p;
(и я не встречал ни одно компилятора на 5 платформах, с которыми я работаю, который вел бы себя иначе).
Пора уже развеивать мифы.
0
Заблокирован
Автор FAQ
27.07.2014, 15:24 13
Цитата Сообщение от DrOffset Посмотреть сообщение
Пора уже развеивать мифы.
- битый поинтер
http://codepad.org/cQqjuIKm
0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
27.07.2014, 15:26 14
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- битый поинтер
http://codepad.org/cQqjuIKm
И как тут поможет if (ptr) ?
1
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
27.07.2014, 15:27 15


Advanced C++ такой advanced
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
27.07.2014, 15:27 16
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
битый поинтер
Действительно. Неужели правда нужно это объяснять?
Цитата Сообщение от gray_fox Посмотреть сообщение
И как тут поможет if (ptr) ?
0
Заблокирован
Автор FAQ
27.07.2014, 15:54 17
DrOffset, по моему ты сейчас кивнул в мою сторону.
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
#include <iostream>
using namespace std;
 
class cObj{
    static int param;
public:
    cObj(){
        param++;
    }
    ~cObj(){
        param--;
    }
    static int GetParam(){
        return param;
    }
    static void Reset(){
        param = 0;
    }
};
 
int cObj::param = 0;
 
void operator delete(void *p)
{
    int param = cObj::GetParam();
    if( param )
        throw param;
}
 
int main(){
    cObj * ptr = new cObj[5];
    ptr = 0;
    if( ptr )
        delete [] ptr;
    else
        cObj::Reset();
    return 0;
}
Фильтровать поинтер нужно всегда, конечно если тут люд кроме консоли нечего не видиывал то понятно, или никогда не перегружал ряд операторов, чтобы отладить какой нибудь нетривиальный проект.
Первый макрос MFC
C++
1
2
3
4
5
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
Добавлено через 4 минуты

Не по теме:

Цитата Сообщение от gray_fox Посмотреть сообщение
И как тут поможет if (ptr) ?
- представь если у тебя несколько дочерних управляемых процессов, которые застрянут если просто так закроешь родительский.

0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
27.07.2014, 15:58 18
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- представь если у тебя несколько дочерних управляемых процессов, которые застрянуть если просто так закроешь родительский.
Иии... как это связано с оператором delete?
0
-=ЮрА=-
27.07.2014, 16:00
  #19

Не по теме:

Цитата Сообщение от gray_fox Посмотреть сообщение
Иии... как это связано с оператором delete?
- раскрой глаза

0
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
27.07.2014, 16:01 20
Цитата Сообщение от DrOffset Посмотреть сообщение
И как тут поможет if (ptr) ?
Подозреваю, что это что-то из разряда:
Цитата Сообщение от -=ЮрА=-
Некоторые вещи я предпочитаю знать лишь один
0
27.07.2014, 16:01
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.07.2014, 16:01
Помогаю со студенческими работами здесь

Ошибки при создании vector'a пользовательского класса
Шалом, мои весьма дорогие друзья, столкнулся с проблемой. Решил использовать вместо массивов...

Ошибки линковки при использовании шаблонного класса
Есть заголовочной файл Utils.h, в котором определены 2 класса String и ArrayList&lt;T&gt;: class...

Ошибки при обращении к функции базового класса
Всем привет. Есть задание: В следующих заданиях требуется создать базовый класс (как вариант...

Какие в данном предложении допущены ошибки или ошибка?
Only after a terrible smell filled the room I realized that the cake had been bunt down.


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru