Klasy abstrakcyjne

0

Mam takie pytanie odnośnie klasy abstrakcyjnej . Czy da się wywołać metodę w klasie abstrakcyjnej?? i dla czego nie mogę umieścić metod w klasa.cpp bo wywala jakiś błąd ??


#include <vcl.h>
#include <iostream.h>
#include "klasa.h"
int main(int argc, char* argv[])
{
       

figure *f[3];

for (int i=0;i<3;i++)
{
        //f[i]=new figure;
        //f[i]->area(); //czy da się jakos wywolac metode area z klasy abstrakcyjnej
        f[i]=new kolo;
        f[i]->area();

 }

for(int i=0;i<3;i++)
        {
        f[i]->area();
        }

        system("pause");
        return 0;
}
//---------------------------------------------------------------------------

klasa.h

#include <iostream.h>

#ifndef KLASA_H
#define KLASA_H

class figure
{
private:
string name;
public:
void setname(string);
figure(){};
virtual void area()=0;

};
class kolo: public figure
{
private:
float r;
public:
kolo();
void area();
};

void kolo::area()
{
cout<<"wzor na pole kola = 2*3.14*a  \n";
cout<<"pole= "<<2*3.14*r<<endl;
}
kolo::kolo()
{
cout<<"podaj promien kola: ";
cin>>r;

}
 void figure::area()
{
cout<<"niezidentyfikowany wzor na pole  \n";
}
#endif 
0

Nie nie da się bo to jest klasa abstrakcyjna. Kompilator nawet nie pozwoli Ci stworzyć instancji figura. A kod:

 void figure::area()
{
cout<<"niezidentyfikowany wzor na pole  \n";
}

Jest niepoprawny bo definiujesz ciało metody abstrakcyjnej (która z domysłu nie ma ciała, na tym polega jej abstrakcyjność).

0

Pozwolę sobie nie zgodzić się z kolegą winterfreshem w kwestii definicji ciała metody abstrakcyjnej-to akurat jest możliwe.

0

ale żeby je wywołać to już chyba nie ?? nie ma jakiegoś tricku ??

0

Cóż,wyobraźmy sobie sytuację:

pointer->BaseAbstractClass::pureVirtualFunction();

na takiego właśnie haka użyteczne jest definiowanie ciała czysto wirtualnej funkcji.
Jeśli mnie pamięć nie myli to da się też wywołać w konstruktorze bazowej klasy abstrakcyjnej(za sec sprawdzę na VS2003)
EDIT:
Dobrze pamiętałem,jest taka możliwość.Ale żeby się zlinkowało to funkcja czysto wirtualna musi mieć zdefiniowane ciało.

0

Klasa abstrakcyjna może mieć zaimplementowane metody jak najbardziej. Nie można stworzyć obiektu takiej klasy. Na przykładzie(za błędy składniowe z góry przepraszam ;)).

class Figura
{
public:
   virtual float Pole() = 0;
   virtual float Obwod() = 0;      
   virtual void JakasFunkcja()
   {
        //coś tutaj robi przydatnego dla wszystkich klas :P
   }
};

class Kwadrat : public Figura
{
public:
   float a;
   Kwadrat(float _a)
   {
      a = _a;
   }
   float Pole()
   {
      JakasFunkcja();
      return a * a;
   }
   float Obwod()
   {
       return a * 4;
   }
};

void main()
{
   Figura * figura = new Kwadrat(4);
   float pole = figura->Pole();
   float obwod  = figura->Obwod();
   figura->JakasFunkcja();
}

Mamy tutaj dwukrotne wywołanie metody klasy abstrakcyjnej ale na rzecz obiektu klasy potomnej. Inaczej ma się sprawa z metodami statycznymi, które wywołuje się na rzecz klasy.

0

MasterBBl właśnie próbowałem za pomocą tego virtualViaPointer ale też mi nie działało mógłbyś mi pokazać na przykładzie ?? ja robiłem tak.

void virtualViaPointer(const figure *);
void virtualViaReference(const figure &);
int main(int argc, char* argv[])
{
   
  kolo ko;
	
	figure *f[3];
	f[0] = &ko;

		
	for ( int i = 0; i < 2; i++)
	{virtualViaPointer(f[i]); }
		
	for ( int j = 0; j < 2; j++)
	{
        virtualViaReference( *f[j] );
	return 0;	
	}
	
	void virtualViaPointer( const figure *base )
	{
	base[i]->area();
        }
	
	void virtualViaReference( const figure &base)
	{
        base.area();
        }
           */

        system("pause");
        return 0;
} 

i wywala błąd [C++ Error] Unit1.cpp(32): E2141 Declaration syntax error tam gdzie jest base[i]->area();

2

Skasowałem ten kod,ale wyglądał mniej więcej tak:

using namespace std;
class Base
{
public:
    virtual void test(void)=0
    {
        cout<<"Class Base\n";
    }
    Base(void)
    {
       test();
    }
};
class Derived : public Base
{
public:
   void test(void)
   {
      cout<<"Class Derived\n";
   }
};

int main(void)
{
  Base *b=new Derived;//pokaże się "Class Base" z funkcji test() wywołanej w konstruktorze Base
  b->test();//tutaj zadziała polimorfizm
  b->Base::test();//tutaj nastąpi wywołanie test() z klasy Base
  return 0;
}
0

wywala mi błąd e2040 przy tworzeniu klasy base, mniejsza o to, ale dzięki b->figure::area(); moge dostać się do metody w klasie abstrakcyjnej dziękuje i o to właśnie mi chodziło :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1