3 / 3 / 1
Регистрация: 08.10.2011
Сообщений: 45
1

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

14.11.2011, 18:35. Показов 2966. Ответов 10
Метки нет (Все метки)

Здравствуйте) опять обращаюсь к вам за помощью))
Дано задание:
Описать базовый класс 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. базовый класс я хоть в том направлении описала?!
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.11.2011, 18:35
Ответы с готовыми решениями:

Заменить наследование классов на наследование интерфейсов
#include &lt;iostream&gt; #include &lt;assert.h&gt; using namespace std; int people_on_base = 100; int...

Наследование шаблоном шаблона (наследование конструктора)
Всем привет! Думаю, что эта тема хоть и касается общих вопросов программирования, но будет уместна...

Наследование интерфейса и наследование реализации
Начал читать книгу GoF и сразу же в предисловии попал в тупик. Чем отличается наследование...

Наследование С# , наследование полей
В классе есть приватное ПОЛЕ . Мне нужно использовать его в классе потомке . Можно это не сделать...

10
Заблокирован
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() я ошибся, увидев ваше ее определение. Вы имеете вв виду не то, что я думал. Тогда можете пропустить мой комментарий относительно этой функции ранее.
1
3 / 3 / 1
Регистрация: 08.10.2011
Сообщений: 45
14.11.2011, 20:12  [ТС] 3
ого!!! и это только базовый классчто же будет дальше(

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

Добавлено через 1 час 1 минуту
все ошибки по базовому классу исправила)
Так покажите, что получилось.
0
3 / 3 / 1
Регистрация: 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 );
}
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;
1
3 / 3 / 1
Регистрация: 08.10.2011
Сообщений: 45
14.11.2011, 23:05  [ТС] 7
вопрос: почему компилятор ругается на строчку

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

Добавлено через 53 секунды
C++
1
2
a << x.get_str();
return a;
1
3 / 3 / 1
Регистрация: 08.10.2011
Сообщений: 45
17.11.2011, 12:21  [ТС] 10
спасибо большое) теперь все работает
0
Делаю внезапно и красиво
Эксперт С++
1312 / 1227 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
17.11.2011, 13:21 11
Учитывая открытое наследование, вспомни про virtual.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.11.2011, 13:21
Помогаю со студенческими работами здесь

Наследование от IEnumerator<T>: как предотвратить наследование IEnumerator
Создаю перечислитель и наследую от IEnumerator&lt;T&gt;, а он, зараза, наследует IEnumerator (который без...

Наследование
class A { private int x; prvate int y; public A():this(1){} public...

наследование
Пытаюсь разобраться в наследовании Есть класс class File { public: struct comp { char...

Наследование
Например, есть у меня класс Person и от него наследуется класс Man. Я вполне могу написать вот...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru