Абстрактные классыНужно написать базовый абстрактный класс, включающий в себя методы Set(), Get()...
Создать несколько производных классов.
Проблема в этом: Создать массив объектов базового класса и заполнить объектами производных классов.
Тут у меня два вопроса:
1) вроде как я не могу создать объект базового АБСТРАКТНОГО класса. я прав?
2) допустим у меня базовый НЕабстрактный класс.
Как в таком случае я могу заполнить массив объектов базового класса объетами производных классов?
Например:
class BasicClass
{
public:
Get(){...}
Set(){...}
};
class Derived1
{
public:
...
}
class Derived2
{
public:
...
}
void main()
{
...
BasicClass* array1=new Derived1[n]; //вот так я создаю массив, заполнив его объектами Derived1. Аналогично могу и со вторым.
//но по условию задачи вроде как просят сделать что-то может наподобие:
BasicClass* array1=new BasicClass;
array[0]=new Derived1; // это неверно, но это я чтобы суть подчеркнуть того, чего я хочу.
}
Вот не знаю, как (и можно ли) заполнить как-нибудь так массив объектов базового класса...
Прошу помощи.
3) и еще: в абстрактом классе у всех ф-ий вначале пишется virtual. А вот что касается конструктора? Перед ним писать virtual нельзя. Тогда получается в абстрактном классе не должно быть конструктора?
А ты уже научился заряжать левой ногой свой телефон?
1) совершенно верно, причем в С++ абстрактным классом считается тот кто имеет хоть одну чисто виртуальную функцию 2) видимо нужно так BasicClass** array1=new Derived1*[n]; array1[0]=new Derived1; 3) конструктор виртуальным нельзя но конструктор должен быть ибо как же все внутренние поля инициализировать
в производном классе его вызов пишется в определении производного конструктора B() : A() { blah blah blah }
и да в С++ в классе с чисто виртуальными функциями могут быть поля как собственно и в любом другом
А ты уже научился заряжать левой ногой свой телефон?
1) ну если ты попробуешь написать BasicClass* a = new BasicClass(123); то компилер даже не пкинет и все создаст, что ни есть гуд
обычно в абстрактных классах методы которые нужно определить в производных пустые и чисто виртуальные то пишут virtual void a() = 0; и усе без определения
если же все методы заполнены то добавляют чисто виртуальный деструктор
virtual ~BasicClass() =0; специально для этих целей при этом даже в такой записи деструктору можно описать тело если нужно
2) а тож, ты же создавал до этого массив объектов класса BasicClass и пытался присвоить ему не объект а указатель на Derived1 сейчас же все ок - массив указателей и суешь ему указатель он и доволен
IDDQD - Команда молодости нашей, команда, без которой мне не жить.
кроме того, что делать с условием задачи... Ну, если в условии задачи под "массивом объектов базового класса" понимать "массив указателей на объекты базового класса" то всё становится просто и понятно. Учитывая, что исходная формулировка бессмысленна в терминах C++, то, очевидно, пользоваться надо уточнённой.
float Trans::CostOfTrip(){ return distance*costbykm; } // ну это я думаю понятно, что такое...
Так вот. Вопрос какой: если бы я не писал базовый класс, и в производном классе вместо class Trans:public BasicClass написал бы просто class Trans, то всё прекрасно работало бы...
Зачем тогда нужен абстрактный класс? Или лучше так: зачем он мне нужен в вот этой программе?
Просто он выглядит как лишняя нашлёпка поверх программы...
А ты уже научился заряжать левой ногой свой телефон?
ну да тут он не нужен, был бы нужен если бы у тебя имелось два производных класса c разной реализации виртуальных функций и в массив BasicClass** ты бы складывал объекты этих двух производных, а потом полиморфно через указатель на базовый звал эти методы в одном цикле к примеру
я тут прост сократил чуток... у меня оно пока что определяется через #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;
Если у меня: BasicClass(float dist) { distance=dist; }
то тогда надо в конструкторе производного класса писать так: Derived1(float dist):BasicClass() //в которую из скобок надо записать float dist? так, как я написал? чтобы инициализировать distance... { ... }
А ты уже научился заряжать левой ногой свой телефон?
эээ как это в какую из скобок, первая - аргумент, хочешь что-то извне положить, без аргумента никак, без типа аргумент не аргумент пришедшее значение через этот самый аргумент затем протаскиваешь в вызываемый правее базовый констркутор
2) видимо нужно так
BasicClass** array1=new Derived1*[n];
array1[0]=new Derived1;
3) конструктор виртуальным нельзя
но конструктор должен быть ибо как же все внутренние поля инициализировать
в производном классе его вызов пишется в определении производного конструктора
B() : A()
{
blah blah blah
}
и да в С++ в классе с чисто виртуальными функциями могут быть поля как собственно и в любом другом
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;
Так что спасибо =)
то компилер даже не пкинет и все создаст, что ни есть гуд
обычно в абстрактных классах методы которые нужно определить в производных пустые и чисто виртуальные то пишут
virtual void a() = 0; и усе без определения
если же все методы заполнены то добавляют чисто виртуальный деструктор
virtual ~BasicClass() =0; специально для этих целей
при этом даже в такой записи деструктору можно описать тело если нужно
2) а тож, ты же создавал до этого массив объектов класса BasicClass и пытался присвоить ему не объект а указатель на Derived1
сейчас же все ок - массив указателей и суешь ему указатель он и доволен
вставил деструктор и сразу объекты BasicClass перестали создаваться =)
добрый компиллятор))
Ну теперь вроде всё на свои места встало))
кроме того, что делать с условием задачи...
ох уж эти преподы =(
Ну, если в условии задачи под "массивом объектов базового класса" понимать "массив указателей на объекты базового класса" то всё становится просто и понятно. Учитывая, что исходная формулировка бессмысленна в терминах C++, то, очевидно, пользоваться надо уточнённой.
Только вот сейчас меня затянул один вопрос ещё...
О целесообразности...
Вот базовый абстрактный класс:
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, то всё прекрасно работало бы...
Зачем тогда нужен абстрактный класс?
Или лучше так: зачем он мне нужен в вот этой программе?
Просто он выглядит как лишняя нашлёпка поверх программы...
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();
}
Я правильно понял?
только я вижу что distance в BasicClass какой-то не инициализированный
и все же array[i]->TimeOfTrip();
это же массив указателей
у меня оно пока что определяется через #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();
}
new Derived1( аргумент1, аргумент2 ... );
new Derived2( аргумент1, аргумент2 ... );
если тебе нужен конструктор базового класса то его надо вызывать через вызов производного конструктора, как это делать я выше приводил
Да, я понял!))
То-то у меня не получалось)))
хм... кажется понял...
Если у меня:
BasicClass(float dist)
{
distance=dist;
}
то тогда надо в конструкторе производного класса писать так:
Derived1(float dist):BasicClass() //в которую из скобок надо записать float dist? так, как я написал? чтобы инициализировать distance...
{
...
}
пришедшее значение через этот самый аргумент затем протаскиваешь в вызываемый правее базовый констркутор
void Derived1(float dist):BasicClass(dist)
{
blah blah blah
}
Да, логично)))
SonicCat спасибо тебе ВО ТАКОЕ =)
Реально по этой теме мне всё по полочкам разложил =)
PS: эх, а я всё-таки тупой =(