#1 09.06.10 19:37
[C++] Классы ошибки в программе
есть файл Reservoirs.h
Код: cpp:
#include <iostream> #include <conio.h> using namespace std; #include <stdio.h> #define StringSize 50 class BaseReservoir { char cName[StringSize]; float fVolume; public: BaseReservoir( void ); BaseReservoir( char cN[StringSize], float fV ) { int iIndex; for( iIndex = 0; cN[iIndex] != 0; iIndex++ ) cName[iIndex] = cN[iIndex]; cName[iIndex] = 0; fVolume = fV; }; ~BaseReservoir(){}; void Scan( BaseReservoir a ) { printf( "Enter the reservoir name\n" ); gets( a.cName ); printf( "Enter reservoir volume\n" ); scanf( "%f", a.fVolume ); } virtual void Print( BaseReservoir a ) { printf( "Reservoir name: %s", cName ); printf( "Reservoir volume: %f", fVolume ); } }; class NaturalReservoir: public BaseReservoir { int iPercentOfCleanliness; public: NaturalReservoir( int iP ): BaseReservoir()// char cN[StringSize], float fV ) { iPercentOfCleanliness = iP; }; ~NaturalReservoir(){}; void Print( BaseReservoir a ) { BaseReservoir::Print(); printf( "Percent of cleanliness of a reservoir: %d%%", iPercentOfCleanliness ); } }; class ArtificialReservoir: public BaseReservoir { char cDate[StringSize]; public: ArtificialReservoir( char cD[StringSize] ): BaseReservoir()// char cN[StringSize], float fV ) { int iIndex; for( iIndex = 0; cD[iIndex] != 0; iIndex++ ) cDate[iIndex] = cD[iIndex]; }; ~ArtificialReservoir(){}; void Print( ArtificialReservoir a ) { BaseReservoir::Print(); printf( "Date of creation of a reservoir: %s", cDate ); } };
и main.cpp
Код: cpp:
#include "Reservoirs.h" #include <stdio.h> #include <conio.h> void main() { BaseReservoir a( "O\0" , 123 ); a.Scan( a ); a.Print( a ); NaturalReservoir b( 40 ); b.Print( b ); ArtificialReservoir c( "12.12.2012" ); c.Print( c ); _getch(); }
есть ошибки которые я не пойму как исправить :(
Исправлено DaZzle (09.06.10 19:47)
Offline
#2 09.06.10 23:16
Re: [C++] Классы ошибки в программе
Код: cpp:
#include <iostream> #include <conio.h> using namespace std; #include <stdio.h> #define StringSize 50 class BaseReservoir { protected: char cName[StringSize]; float fVolume; public: BaseReservoir( void ){}; BaseReservoir( char cN[StringSize], float fV ) { int iIndex; for( iIndex = 0; cN[iIndex] != 0; iIndex++ ) cName[iIndex] = cN[iIndex]; cName[iIndex] = 0; fVolume = fV; }; BaseReservoir(BaseReservoir& a) { int iIndex; for( iIndex = 0; a.cName[iIndex] != 0; iIndex++ ) this->cName[iIndex] = a.cName[iIndex]; this->cName[iIndex] = 0; fVolume=a.fVolume; }; ~BaseReservoir(){}; void Scan() { printf( "Enter the reservoir name\n" ); gets( cName ); printf( "Enter reservoir volume\n" ); scanf( "%f", &fVolume ); }; virtual void Print() { printf( "Reservoir name: %s", cName ); printf( "Reservoir volume: %f", fVolume ); }; }; class NaturalReservoir: public BaseReservoir { int iPercentOfCleanliness; public: NaturalReservoir( int iP,BaseReservoir& a ): BaseReservoir(a)// char cN[StringSize], float fV ) { iPercentOfCleanliness = iP; }; ~NaturalReservoir(){}; void Print() { BaseReservoir::Print(); printf( "Percent of cleanliness of a reservoir: %d%%", iPercentOfCleanliness ); }; }; class ArtificialReservoir: public BaseReservoir { char cDate[StringSize]; public: ArtificialReservoir( char cD[StringSize],BaseReservoir& a ): BaseReservoir(a)// char cN[StringSize], float fV ) { int iIndex; for( iIndex = 0; cD[iIndex] != 0; iIndex++ ) cDate[iIndex] = cD[iIndex]; cDate[iIndex]=0; }; ~ArtificialReservoir(){}; void Print() { BaseReservoir::Print(); printf( "Date of creation of a reservoir: %s", cDate ); }; };
Код: cpp:
#include "Header.h" #include <stdio.h> #include <conio.h> void main() { BaseReservoir a( "O\0" , 123 ); a.Scan(); a.Print(); NaturalReservoir b( 40 ,a); b.Print(); ArtificialReservoir c( "12.12.2012" ,a); c.Print(); _getch(); }
Можно и так. Код ужасный, но, вроде, работает.
Исправлено Revenger (09.06.10 23:17)
Offline
#7 10.06.10 00:08
Re: [C++] Классы ошибки в программе
Revenger, теперь у меня другая проблема я когда пытаюсь обратится к функции ввода то есть к скану из маине он почему-то пропускает строчку ввода Имени
Код: cpp:
void main() { BaseReservoir a; a.Scan(); NaturalReservoir a1( 40 , a ); a1.Print(); BaseReservoir c; c.Scan(); ArtificialReservoir c1( "12.12.2012" , c ); c1.Print(); _getch(); }
Offline
#9 10.06.10 00:13
Re: [C++] Классы ошибки в программе
ну вот смотри, мне нужно ввести как бы два названия и объёма, но вместе с первыми данными о имени и объёми он должен вставить процент чистоты, а для вторых должен вывести дату созданию, и вот когда я обращаюсь к скану второй раз ну то есть BaseReservoir c; c.Scan(); он строчку ввода имени пропускает и сразу вводит объём. следовательно второй вывод получается без имени
Offline
#10 10.06.10 00:25
Re: [C++] Классы ошибки в программе
Я ж говорю код изначально косячный, но переписывать все мне лениво
Код функции Scan в базовом классе(BaseReservoir):
Код: cpp:
void Scan() { printf( "Enter the reservoir name\n" ); fflush(stdin); gets( cName ); printf( "Enter reservoir volume\n" ); scanf( "%f", &fVolume ); };
Попробуй так
Исправлено Revenger (10.06.10 00:25)
Offline
#11 10.06.10 00:27
#12 10.06.10 00:38
#13 10.06.10 00:42
#14 10.06.10 00:47
#15 10.06.10 01:05
#16 10.06.10 01:05
#17 10.06.10 01:07
#18 10.06.10 01:09
#19 10.06.10 01:09
Re: [C++] Классы ошибки в программе
$up написал(а):
Никто не создаёт экземпляр класса лишь затем, чтобы отдать в конструктор наследнику.
Я понимаю. Но техзадание стояло - исправить, чтоб работало. Ошибки компиляции убрал - тз выполнено)))
Но ведь можно же отдать экземпляр класса конструктору наследника. возникает ведь такая необходимость.
Offline
#20 10.06.10 01:10
#21 10.06.10 01:11
#22 10.06.10 01:12
#23 10.06.10 01:13
#24 10.06.10 01:18
Re: [C++] Классы ошибки в программе
Lunat1k написал(а):
А, тогда тут всё понятно
Что же тебе понятно?
пример
Код: cpp:
class Base { private: char *sp1; public: Base(const char *S) { sp1=strdup(S); } ~Base() { delete sp1; } }; class Derived: public Base { private: char *sp2; public: Derived(const char *S1, const char *S2): Base(S1) { sp2=strdup(S2); } ~Derived() { delete sp2; } };
Как сработает вот это
Код: cpp:
Base *pBase; pBase=new Derived("string 1", "string 2"); delete pBase;
И в чем будет отличие, если деструктор Base был бы виртуальным?
Исправлено Revenger (10.06.10 01:49)
Offline
#25 10.06.10 01:43
#26 10.06.10 01:50
#27 11.06.10 09:50
#28 11.06.10 10:01
Re: [C++] Классы ошибки в программе
Banzzaj написал(а):
Revenger, ты бы уже объяснил :) я не знаю
Ты пошутил, или серьёзно?
Revenger написал(а):
Затем, чтобы при полиморфизме деструкторы наследников корректно вызвались
В нашем примере, pBase указатель на Base, но объект должен вести себя как Derived. И конечно при вызове деструктора этого объекта, ты хочешь уничтожит именно его. Но без virtual destructor вызовется только деструктор объекта Base(откуда компилятору знать тип объекта по указателю). И у тебя получается утечка памяти. С virtual destructor все пройдет корректно и вызовутся деструкторы как Base так и Derived. Память никуда не утечет.
З.Ы. Как то кривовато я объяснил.
Offline
#29 11.06.10 10:13
#30 11.06.10 12:50
Re: [C++] Классы ошибки в программе
При определении любой виртуальной функции объект класса увеличивается на указатель на таблицу виртуальных функций(vtable).
Вот тебе про таблицу - лень писать
http://ru.wikipedia.org/wiki/Таблица_ви … ых_методов
Исправлено Revenger (11.06.10 12:52)
Offline

