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

наследование С++ - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.95
Lennadij
3 / 3 / 0
Регистрация: 08.10.2011
Сообщений: 45
14.11.2011, 18:35     наследование С++ #1
Здравствуйте) опять обращаюсь к вам за помощью))
Дано задание:
Описать базовый класс CStr – строка. Описать производный от СStr класс CSStr – шестнадцатеричная строка. Строки данного класса могут содержать только шестнадцатиричные символы. Если в составе инициализирующей строки будут встречены любые символы, отличные от допустимых, строка принимает нулевое значение.Содержимое данной строки рассматривается как знаковое шестнадцатеричное число. Класс CSStr содержит следующие методы: конструктор без параметров; конструктор, принимающий в качестве параметра Си-строку (заканчивается нулевым байтом); конструктор копирования; деструктор, метод, преобразующий данную строку в целое десятичное число, метод изменение знака на противоположный (перевод числа в дополни-тельный код). Переопределить следующие операции: присваивание (=); сложение (+) — арифметическая сумма строк; операция (==) — проверка на равенство. Написать демонстрационную программу.

С базовым классов вроде как то разобралась. А вот с производным ни как(
Вот код базового класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#ifndef __Str_H
#define __Str_H
 
class CStr
{protected: 
    char* s;//Поле для хранения строки
    int len;//Поле для хранения длины сроки 
public:
    CStr();//Kонструктор без параметров
    CStr(char*);//Конструктор создания строки, равной заданной С- строке
    CStr(const CStr&);//Kонструктор копирования
    CStr& operator=(const CStr&);
    bool operator ==(CStr &);
    void empty();
    char * get_str()  const {return s;} //Метод  получения строки
    ~CStr(){delete[]s;}//Деструктор
    int get_len() const {return len;}// Метод получения длины строки
    
};
#endif
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
#include "StdAfx.h"
#include "Str.h"
#include <iostream>
#include <iomanip>
using namespace std;
 
// Конструктор создания пустой строки
CStr::CStr():len(0)
{s=new char;*s='\0'; cout<<"\nContructor1";}
 
// Конструктор создания строки, равной заданной С- строке
CStr::CStr(char* a)
{s=new char[len=strlen(a)];
    strcpy(s,a);
    cout<<"\nContructor2";
}
 
// Конструктор копирования
CStr::CStr(const CStr& a)
{s=new char[len=a];strcpy(s,a.s);cout<<"\nContructor3 ";}
 
// Операция присваивания
CStr& CStr::operator = (const CStr & a)
{
    if (&a==this)  return *this;
    if (len) delete []s;
    s=new char [len=a];
    strcpy(s,a.s);
    cout<<" \nDONE == ";
    return *this;
}
 
// Операция сравнения строк
bool CStr::operator ==(CStr & st)
{
if (strcmp (s, st.s)==0) return true;
return false;
}
 
// Метод, делающий строку пустой
void CStr::empty()
{ if (len)   
    { len = 0; delete []s; s = new char; *s= '\0';} 
}
 
// Операция записи в поток вывода на экран
ostream& operator<<(ostream& a, CStr& x)
{return a<<x.s;}
P.S. базовый класс я хоть в том направлении описала?!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.11.2011, 18:35     наследование С++
Посмотрите здесь:

Наследование C++
Наследование C++
C++ наследование
C++ Наследование
Наследование C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Сыроежка
Заблокирован
14.11.2011, 19:04     наследование С++ #2
Замечания по базовому классу.

Вместо

C++
1
CStr(char*);//Конструктор создания строки, равной заданной С- строке
лучше написать

C++
1
CStr( const char*);//Конструктор создания строки, равной заданной С- строке
Оператор-функцию

C++
1
bool operator ==(CStr &);
лучше сделать не членом класса. Так как у вас есть конструктор, принимающий символьную строку, то вы тогда сможете сравнивать объект вашего класса с произвольной символьной строкой. Поэтому эта функция должна выглядеть следующим образом

C++
1
bool operator ==( const CStr &, const CStr & );
и должна быть объявлена вне класса.

Смысл этой функции

C++
1
void empty();
совершенно не понятен. Скорей всего вы имели в виду, что эта функция должна возвращать логическое значение

C++
1
bool empty() const;
Функцию

C++
1
char * get_str()  const {return s;} //Метод  получения строки
лучше определить таким образом, чтобы результат нельзя было изменять, то есть

C++
1
const char * get_str()  const {return s;} //Метод  получения строки
Мне представляется, что конструктор

C++
1
2
CStr::CStr():len(0)
{s=new char;*s='\0'; cout<<"\nContructor1";}
можно определить проще, К тому же ваш конструктор содержит ошибку, так как вместо new char[1] вы используете new char, а в деструкторе у вас используется delete [] s, а не delete s

C++
1
2
3
4
CStr::CStr():len(0), s( new char[1] )
{
   *s='\0'; cout<<"\nContructor1";
}
Данный конструктор содержит ошибку

C++
1
2
3
4
CStr::CStr(char* a)
{s=new char[len=strlen(a)];
        strcpy(s,a);
        cout<<"\nContructor2";
нужно к strlen( a ) прибавить 1 для нулевого завершающего символа. К тому же параметр должен иметь квалификатор const

C++
1
2
3
4
5
CStr::CStr(const char* a) : len( strlen( a ) ), s( new char[len+1] )
{
        strcpy(s,a);
        cout<<"\nContructor2";
}
Только мой пример конструктора базируется на том, что в вашем классе сначала должна быть объявлена переменная len, а после нее переменная s, так как порядок инициализации переменных в списке инициализации конструктора зависит от порядка объявления членов класса.

Конструктор копирования с учетом мною сказанного выше будет выглядеть следующим образом

C++
1
2
3
4
5
6
// Конструктор копирования
CStr::CStr(const CStr& a) : len( a.len ), s( new char[len+1] )
{
   strcpy(s,a.s);
   cout<<"\nContructor3 ";
}
В операторе присваивания у вас ошибка

C++
1
2
3
4
5
6
7
8
9
CStr& CStr::operator = (const CStr & a)
{
        if (&a==this)  return *this;
        if (len) delete []s;
        s=new char [len=a];
        strcpy(s,a.s);
        cout<<" \nDONE == ";
        return *this;
}
Согласно вашему дизайну класса переменная len может быть равной 0, но при этом вы выделяли память под один нулевой символ.
Поэтому освобождение памяти должно быть безусловной! Вы всегда, когда создаете объект класса, выделяете память для s.


Как я уже написал, оператор сравнения лучше сделать не членом класса

C++
1
2
3
4
bool operator ==(const CStr & lhs, const CStr &rhs )
{
   return ( strcmp( lhs.get_str(), rhs.get_str() ) == 0 );
}
С функцией emplty() я ошибся, увидев ваше ее определение. Вы имеете вв виду не то, что я думал. Тогда можете пропустить мой комментарий относительно этой функции ранее.
Lennadij
3 / 3 / 0
Регистрация: 08.10.2011
Сообщений: 45
14.11.2011, 20:12  [ТС]     наследование С++ #3
ого!!! и это только базовый классчто же будет дальше(

Добавлено через 1 час 1 минуту
все ошибки по базовому классу исправила)
насчет производного пока еще не поняла...
Сыроежка
Заблокирован
14.11.2011, 20:14     наследование С++ #4
Цитата Сообщение от Lennadij Посмотреть сообщение
ого!!! и это только базовый классчто же будет дальше(

Добавлено через 1 час 1 минуту
все ошибки по базовому классу исправила)
Так покажите, что получилось.
Lennadij
3 / 3 / 0
Регистрация: 08.10.2011
Сообщений: 45
14.11.2011, 20:29  [ТС]     наследование С++ #5
в общем вот, я так понимаю описание производного класса будет еще сложнее?!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#ifndef __Str_H
#define __Str_H
 
class CStr
{protected: 
        int len;//Поле для хранения длины сроки 
        char* s;//Поле для хранения строки
        
public:
        CStr();//Kонструктор без параметров
        CStr( const char*);//Конструктор создания строки, равной заданной С- строке
        CStr(const CStr&);//Kонструктор копирования
        CStr& operator=(const CStr&);
        bool operator ==(CStr &);
        void empty();
        const char * get_str()  const {return s;} //Метод  получения строки
        int get_len() const {return len;}// Метод получения длины строки
        ~CStr(){delete[]s;}//Деструктор        
};
        bool operator ==( const CStr &, const CStr & ); 
#endif


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 "StdAfx.h"
#include "Str.h"
#include <iostream>
#include <iomanip>
using namespace std;
 
// Конструктор создания пустой строки
CStr::CStr():len(0), s( new char[1] )
{
   *s='\0'; cout<<"\nContructor1";
}
 
// Конструктор создания строки, равной заданной С- строке
CStr::CStr(const char* a) : len( strlen( a ) ), s( new char[len+1] )
{
        strcpy(s,a);
        cout<<"\nContructor2";
}
 
// Конструктор копирования
CStr::CStr(const CStr& a) : len( a.len ), s( new char[len+1] )
{
   strcpy(s,a.s);
   cout<<"\nContructor3 ";
}
 
// Операция присваивания
CStr& CStr::operator = (const CStr & a)
{
        if (&a==this)  return *this;
        if (len) delete []s;
        s=new char [len=a];
        strcpy(s,a.s);
        cout<<" \nDONE == ";
        return *this;
}
 
// Операция сравнения строк
bool CStr::operator ==(CStr & st)
{
if (strcmp (s, st.s)==0) return true;
return false;
}
 
// Метод, делающий строку пустой
void CStr::empty()
{ if (len)   
        { len = 0; delete []s; s = new char; *s= '\0';} 
}
 
// Операция записи в поток вывода на экран
ostream& operator<<(ostream& a, CStr& x)
{return a<<x.s;}
 
bool operator ==(const CStr & lhs, const CStr &rhs )
{
   return ( strcmp( lhs.get_str(), rhs.get_str() ) == 0 );
}
Сыроежка
Заблокирован
14.11.2011, 20:34     наследование С++ #6
Цитата Сообщение от Lennadij Посмотреть сообщение
в общем вот, я так понимаю описание производного класса будет еще сложнее?!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#ifndef __Str_H
#define __Str_H
 
class CStr
{protected: 
        int len;//Поле для хранения длины сроки 
        char* s;//Поле для хранения строки
        
public:
        CStr();//Kонструктор без параметров
        CStr( const char*);//Конструктор создания строки, равной заданной С- строке
        CStr(const CStr&);//Kонструктор копирования
        CStr& operator=(const CStr&);
        bool operator ==(CStr &);
        void empty();
        const char * get_str()  const {return s;} //Метод  получения строки
        int get_len() const {return len;}// Метод получения длины строки
        ~CStr(){delete[]s;}//Деструктор        
};
        bool operator ==( const CStr &, const CStr & ); 
#endif


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 "StdAfx.h"
#include "Str.h"
#include <iostream>
#include <iomanip>
using namespace std;
 
// Конструктор создания пустой строки
CStr::CStr():len(0), s( new char[1] )
{
   *s='\0'; cout<<"\nContructor1";
}
 
// Конструктор создания строки, равной заданной С- строке
CStr::CStr(const char* a) : len( strlen( a ) ), s( new char[len+1] )
{
        strcpy(s,a);
        cout<<"\nContructor2";
}
 
// Конструктор копирования
CStr::CStr(const CStr& a) : len( a.len ), s( new char[len+1] )
{
   strcpy(s,a.s);
   cout<<"\nContructor3 ";
}
 
// Операция присваивания
CStr& CStr::operator = (const CStr & a)
{
        if (&a==this)  return *this;
        if (len) delete []s;
        s=new char [len=a];
        strcpy(s,a.s);
        cout<<" \nDONE == ";
        return *this;
}
 
// Операция сравнения строк
bool CStr::operator ==(CStr & st)
{
if (strcmp (s, st.s)==0) return true;
return false;
}
 
// Метод, делающий строку пустой
void CStr::empty()
{ if (len)   
        { len = 0; delete []s; s = new char; *s= '\0';} 
}
 
// Операция записи в поток вывода на экран
ostream& operator<<(ostream& a, CStr& x)
{return a<<x.s;}
 
bool operator ==(const CStr & lhs, const CStr &rhs )
{
   return ( strcmp( lhs.get_str(), rhs.get_str() ) == 0 );
}
Вам надо удалить из класса ваш оператор сравнения, так как мы его заменили глобальным оператором сравнения, а в операторе присваивания вы ошибку не исправили.

Следующий код в операторе присваивания

C++
1
        if (len) delete []s;
некорректный, так как, как я уже писал, len может быть равной 0, но тем не менее вы выделяли память для хранения нулевого символа в строке s. Поэтому удалять память нужно безусловно.

C++
1
        delete []s;
Lennadij
3 / 3 / 0
Регистрация: 08.10.2011
Сообщений: 45
14.11.2011, 23:05  [ТС]     наследование С++ #7
вопрос: почему компилятор ругается на строчку

C++
1
{return a<<x.s;}
Добавлено через 2 часа 26 минут
когда вставляю в первый файл friend ostream& operator<<(ostream&,CStr&);также выдается ошибка?
Lennadij
3 / 3 / 0
Регистрация: 08.10.2011
Сообщений: 45
17.11.2011, 12:12  [ТС]     наследование С++ #8
может кто нибудь ответит?! интересно узнать в чем ошибка)
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
17.11.2011, 12:14     наследование С++ #9
Lennadij, Ошибку угадать надо?

Добавлено через 53 секунды
C++
1
2
a << x.get_str();
return a;
Lennadij
3 / 3 / 0
Регистрация: 08.10.2011
Сообщений: 45
17.11.2011, 12:21  [ТС]     наследование С++ #10
спасибо большое) теперь все работает
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.11.2011, 13:21     наследование С++
Еще ссылки по теме:

Наследование C++
C++ Наследование
Наследование C++

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

Или воспользуйтесь поиском по форуму:
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
17.11.2011, 13:21     наследование С++ #11
Учитывая открытое наследование, вспомни про virtual.
Yandex
Объявления
17.11.2011, 13:21     наследование С++
Ответ Создать тему
Опции темы

Текущее время: 08:15. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru