Консультация № 180169
05.10.2010, 20:34
49.63 руб.
0 5 1
Здравствуйте, уважаемые эксперты!
Помогите реализовать и разобраться со следующей задачей:

Coздaть клaсс, oбъeкт кoтoрoгo рeaлизуeт "пoльзoвательский" тип дaнных (см. прилoжение). Oбeспeчить прoизвoльную рaзмeрнoсть зa счeт испoльзования в oбъекте динaмичeских стрyктyр дaнных. Создaть кoнструктор, дeструктор, кoнструктор кoпирования, а тaкже мeтоды, oбeспeчивaющиe измeнeниe oтдeльных сoстaвных чaстeй oбъeктa и вывoд eгo сoдержимoгo.

Заранее спасибо!

Приложение:
Цeлoe прoизвoльнoй длины в двoичнo-десятичнoй фoрме прeдставлeния в видe: дeсятичная цифрa - тeтрaдa, пo двe тaтрaды в oднoм бaйтe. Пoследoвательнoсть цифр хрaнится, нaчинaя с млaдшeй, и oгрaничeна тетрадoй с кoдoм 0xF.

Обсуждение

Неизвестный
06.10.2010, 07:54
общий
06.10.2010, 13:30
это ответ
Здравствуйте, Волков Сергей Юриевич.

Например, вот так(см. приложение):

Я использовал stl::vector для создания динамического массива данных.
В качестве входных параметров для конструкторов использовал числа и строки, содержащие числа.

Приложение:
#include <iostream>

#include <vector>
using namespace std;

class CClass
{
vector<unsigned char> m_Data;

public:
CClass(int iData);
CClass(char *pszData);
CClass(CClass& cls);
virtual ~CClass();

void clear();

int at(unsigned int uidx);
int setat(unsigned int uidx, int value);
int size();

CClass& operator =(CClass cls);
friend ostream& operator << (ostream&str, CClass cls);
};

CClass::CClass(int iData)
{
// swithcer
bool bLow = true;
// parse
while (iData)
{
if(bLow)
{
m_Data.push_back(0);
m_Data.back() = iData%10;
}
else
{
int i = (((iData%10)&0xf)<<4);
m_Data.back() |= (((iData%10)&0xf)<<4);
}

bLow = !bLow;
iData = iData/10;
}
// tail
if(bLow)
{
m_Data.push_back(0);
m_Data.back() = 0xf;
}
else
m_Data.back() |= 0xf0;
}

CClass::CClass(char *pszData)
{
// swithcer
bool bLow = true;
int iData;
// parse
if(NULL != pszData)
{
char *psz = pszData;
while (*++pszData);
pszData--;
while (pszData>=psz)
{
iData = (*pszData)- '0';
if(iData >= 0 && iData <=9)
if(bLow)
{
m_Data.push_back(0);
m_Data.back() = iData;
}
else
m_Data.back() |= iData<<4;

bLow = !bLow;
pszData--;
}
}
// tail
if(bLow)
{
m_Data.push_back(0);
m_Data.back() = 0xf;
}
else
m_Data.back() |= 0xf0;
}

CClass::CClass(CClass& cls)
{
vector<unsigned char>::iterator it = cls.m_Data.begin();
for(; it<cls.m_Data.end(); it++)
m_Data.push_back(*it);
}

CClass::~CClass()
{
clear();
}

//-----------------------------------
int CClass::at(unsigned int uidx)
{
if(uidx >= size())
return 0xE; // error
if(!(uidx%2))
return m_Data[uidx/2] & 0xf;
else
return (m_Data[uidx/2] & 0xf0)>>4;
}

int CClass::setat(unsigned int uidx, int value)
{
int iRes, iVal;
if(uidx >= size())
return 0xE; // error
if(!(uidx%2))
{
iVal = m_Data[uidx/2];
iRes = iVal & 0x0f;
iVal = iVal & 0xf0; // clear
iVal = iVal | (value & 0x0f);
m_Data[uidx/2] = iVal;
}
else
{
iVal = m_Data[uidx/2];
iRes = (iVal & 0xf0)>>4;
iVal = iVal & 0x0f; // clear
iVal = iVal | ((value<<4) & 0xf0);
m_Data[uidx/2] = iVal;
}
return iRes;
}

int CClass::size()
{
int iSize = m_Data.size();
if(m_Data[iSize-1] > 0xf)
iSize = iSize*2-1;
else
iSize = iSize*2-2;
return iSize;
}

//-----------------------------------
CClass& CClass::operator =(CClass cls)
{
clear();
vector<unsigned char>::iterator it = cls.m_Data.begin();
for(; it<cls.m_Data.end(); it++)
m_Data.push_back(*it);
return *this;
}

ostream& operator << (ostream&str, CClass cls)
{
int iSize = cls.size();
for(int i=iSize-1; i>=0; i--)
{
str<<cls.at(i);
}
return str;
}

//-----------------------------------
void CClass::clear()
{
m_Data.clear();
}

//-----------------------------------
int main(int argc, char* argv[])
{
CClass c1(152);
CClass c2("12345457763");
CClass c3(c2);
c3.setat(0, 7);
c3.setat(3, 8);
CClass c4(0), c5(1);
c5 = c4 = c1;
c5.setat(2, 3);
cout<< "c1: " << c1 << ", c2: " << c2 << ", c3: " << c3 << ", c4: " << c4 << ", c5: " << c5;
return 0;
}
Неизвестный
06.10.2010, 11:23
общий
Сандров Алекс:
Привет, есть вопросы по вашей программе:
- зачем вам хвостовик 0xF ? По-моему можно прекрасно обойтись без него.
- в функциях at/setat нужна более аккуратная проверка действительности индекса цифры.
Неизвестный
06.10.2010, 11:53
общий
coremaster1:
- ну, оно там по заданию требовалось, а так, да, оно в _моём_ решении - не нужно. Но мы тут подискутировали на тему задания и моего решения, есть одна из мыслей, что автор задачи планировал, что решение будет сделано без класса vector, на основе динамического выделения памяти и использования 0xf в качестве признака конца последовательности.
- да, верно, надо было unsigned int поставить :(
btw, в операторе = в качестве параметра надо использовать ссылку:
Код:
CClass& CClass::operator =(CClass& cls)
...
Неизвестный
06.10.2010, 12:29
общий
Сандров Алекс:
Извиняюсь насчёт хвостовика, не дочитал задание
В проверке проблема в другом, она допускает обращение к хвостовику и вообще за границу вектора.
Неизвестный
06.10.2010, 13:01
общий
Да, верно , надо проверять вот так:

Код:
	if(idx >= size())
return 0xE; // error


В обеих функциях.
Форма ответа