Хочешь чуда? Будь чудом!
Абстрактные классы

@темы: C++

Комментарии
22.09.2010 в 22:18

А ты уже научился заряжать левой ногой свой телефон?
1) совершенно верно, причем в С++ абстрактным классом считается тот кто имеет хоть одну чисто виртуальную функцию
2) видимо нужно так
BasicClass** array1=new Derived1*[n];
array1[0]=new Derived1;
3) конструктор виртуальным нельзя
но конструктор должен быть ибо как же все внутренние поля инициализировать

в производном классе его вызов пишется в определении производного конструктора
B() : A()
{
blah blah blah
}

и да в С++ в классе с чисто виртуальными функциями могут быть поля как собственно и в любом другом
22.09.2010 в 22:29

Хочешь чуда? Будь чудом!
1) Вот это у меня какой класс?

class BasicClass
{
protected:
float distance;
float speed;
float costbykm;
public:
BasicClass() {
distance=dist;
}

BasicClass(float distan) {
distance=distan;
}

virtual void SetSpeed(float sp) {
speed=sp;
}

virtual void SetCost(float cost) {
costbykm=cost;
}

virtual float GetSpeed() {
return speed;;
}

virtual float GetCost() {
return costbykm;
}

virtual void TimeOfTrip(float distance,float speed) {
cout << (distance/speed) << " hours";
}

virtual void CostOfTrip(float distance,float costbykm) {
cout << (distance*costbykm) << " dollars";
}
};

2) Прокатывает так: BasicClass** array1=new BasicClass*[n];
array1[0]=new Derived1;
Так что спасибо =)
22.09.2010 в 22:34

А ты уже научился заряжать левой ногой свой телефон?
1) ну если ты попробуешь написать BasicClass* a = new BasicClass(123);
то компилер даже не пкинет и все создаст, что ни есть гуд

обычно в абстрактных классах методы которые нужно определить в производных пустые и чисто виртуальные то пишут
virtual void a() = 0; и усе без определения

если же все методы заполнены то добавляют чисто виртуальный деструктор

virtual ~BasicClass() =0; специально для этих целей
при этом даже в такой записи деструктору можно описать тело если нужно

2) а тож, ты же создавал до этого массив объектов класса BasicClass и пытался присвоить ему не объект а указатель на Derived1
сейчас же все ок - массив указателей и суешь ему указатель он и доволен
23.09.2010 в 16:50

Хочешь чуда? Будь чудом!
о =)
вставил деструктор и сразу объекты BasicClass перестали создаваться =)
добрый компиллятор))
Ну теперь вроде всё на свои места встало))

кроме того, что делать с условием задачи...
ох уж эти преподы =(
24.09.2010 в 09:58

IDDQD - Команда молодости нашей, команда, без которой мне не жить.
кроме того, что делать с условием задачи...
Ну, если в условии задачи под "массивом объектов базового класса" понимать "массив указателей на объекты базового класса" то всё становится просто и понятно. Учитывая, что исходная формулировка бессмысленна в терминах C++, то, очевидно, пользоваться надо уточнённой. ;)
24.09.2010 в 16:54

Хочешь чуда? Будь чудом!
Ага-ага.

Только вот сейчас меня затянул один вопрос ещё...
О целесообразности...

Вот базовый абстрактный класс:

class BasicClass{

protected:

float distance;

public:

BasicClass(float dist) {
distance=dist;
}

virtual float TimeOfTrip(void)=0;

virtual float CostOfTrip(void)=0;
};

Вот его производный класс:

class Trans:public BasicClass{

float speed;
float costbykm;

public:

Trans(){
speed=500;
costbykm=0.7;
}

float TimeOfTrip(); // это та функция, что в базовом классе виртуальная
float CostOfTrip(); // это та функция, что в базовом классе виртуальная
};

void Trans::Set(float sp,float cost)
{
speed=sp;
costbykm=cost;
}

float Trans::TimeOfTrip(){
return distance/speed;
}

float Trans::CostOfTrip(){
return distance*costbykm;
} // ну это я думаю понятно, что такое...

Так вот.
Вопрос какой: если бы я не писал базовый класс, и в производном классе вместо class Trans:public BasicClass написал бы просто class Trans, то всё прекрасно работало бы...

Зачем тогда нужен абстрактный класс?
Или лучше так: зачем он мне нужен в вот этой программе?

Просто он выглядит как лишняя нашлёпка поверх программы...
24.09.2010 в 17:29

А ты уже научился заряжать левой ногой свой телефон?
ну да тут он не нужен, был бы нужен если бы у тебя имелось два производных класса c разной реализации виртуальных функций и в массив BasicClass** ты бы складывал объекты этих двух производных, а потом полиморфно через указатель на базовый звал эти методы в одном цикле к примеру
24.09.2010 в 17:33

Хочешь чуда? Будь чудом!
То есть как-то так?

void main()
{

BasicClass** array=new BasicClass* [2];
array[0]=new Derived1;
array[1]=new Derived2;

for(int i=0;i<2;i++)
array[i].TimeOfTrip();

}

Я правильно понял?
24.09.2010 в 17:41

А ты уже научился заряжать левой ногой свой телефон?
угу
только я вижу что distance в BasicClass какой-то не инициализированный

и все же array[i]->TimeOfTrip();
это же массив указателей
24.09.2010 в 17:48

Хочешь чуда? Будь чудом!
я тут прост сократил чуток...
у меня оно пока что определяется через #define dist 700, а в конструкторе уже distance=dist...

и все же array[i]->TimeOfTrip();
это же массив указателей

ага - да точно. спасибо =)

вот еще тогда спрошу:
например у меня конструктор:

BasicClass(float dist)
{
distance=dist;
}

Как мне тогда создать массив в main?

void main()
{
float n;
cin >> n;
BasicClass** array=new BasicClass* [2];// куда в этом случае впихнуть параметр?.. BasicClass** array(n)=new BasicClass* [2], так что ли?
array[0]=new Derived1;
array[1]=new Derived2;

for(int i=0;i<2;i++)
array[i]->TimeOfTrip();
}
24.09.2010 в 18:35

А ты уже научился заряжать левой ногой свой телефон?
new BasicClass* [2]; - это массив тут некуда

new Derived1( аргумент1, аргумент2 ... );
new Derived2( аргумент1, аргумент2 ... );

если тебе нужен конструктор базового класса то его надо вызывать через вызов производного конструктора, как это делать я выше приводил
24.09.2010 в 19:01

Хочешь чуда? Будь чудом!
Точно!
Да, я понял!))

То-то у меня не получалось)))

хм... кажется понял...

Если у меня:
BasicClass(float dist)
{
distance=dist;
}

то тогда надо в конструкторе производного класса писать так:
Derived1(float dist):BasicClass() //в которую из скобок надо записать float dist? так, как я написал? чтобы инициализировать distance...
{
...
}
24.09.2010 в 19:07

А ты уже научился заряжать левой ногой свой телефон?
эээ как это в какую из скобок, первая - аргумент, хочешь что-то извне положить, без аргумента никак, без типа аргумент не аргумент
пришедшее значение через этот самый аргумент затем протаскиваешь в вызываемый правее базовый констркутор

void Derived1(float dist):BasicClass(dist)
{
blah blah blah
}
24.09.2010 в 19:10

Хочешь чуда? Будь чудом!
Ох ты)))
Да, логично)))

SonicCat спасибо тебе ВО ТАКОЕ =)
Реально по этой теме мне всё по полочкам разложил =)

PS: эх, а я всё-таки тупой =(