Funkcje wirtualne w klasach

0

Mam problem odnośnie funkcji, metod wirtualnych bo nie rozumiem ich za bardzo i nie wiem jak sprawić, żeby działały w programie.
Jakby był ktoś chętny, żeby pomóc to wielkie dzięki i powiedzieć dlaczego tak a nie inaczej. Chcę zrobić funkcję wirtualną wypisującą dane.

Plik główny - klasa.h

#ifndef UBRANIE_H_
#define UBRANIE_H_
#include <cstring>
#include <ostream>


using namespace std;


class AbstrUbranie
{
    protected:
char* nazwa;
char* material;
int wzrost;

    public:
    virtual ~AbstrUbranie(){};
    virtual void dane();
    virtual void wypisz();

};


class Ubranie: public AbstrUbranie
{
protected:

static int ilosc;
char* nazwa;
char* material;
int wzrost;

public:
Ubranie();
~Ubranie();
// virtual void f();
Ubranie & operator=(const Ubranie &);
Ubranie (const Ubranie &);
Ubranie (const char*, const char*, int);
friend ostream & operator<<(ostream &, const Ubranie &);
static int iloscUbran();
virtual void dane();
virtual void wypisz();
};

class UbranieSportowe: public Ubranie
{
    private:
    char* doJakiegoSportu;

    public:
    UbranieSportowe(char* ds=" ", const char* naz=" ", const char* mat=" ", int wzrost=0);
    UbranieSportowe(char* ds, const Ubranie &u);
    char* getDoJakiegoSportu() {return doJakiegoSportu;}
    void setDoJakiegoSportu(char* ds) {doJakiegoSportu=ds;}
    friend ostream & operator<<(ostream &, const UbranieSportowe &);
    virtual void dane();
    virtual void wypisz();

};

class UbranieWyjsciowe: public Ubranie
{
    private:
    char* naJakaOkazje;

    public:
    UbranieWyjsciowe(char* njk=" ", const char* naz=" ", const char* mat=" ", int wzrost=0);
    UbranieWyjsciowe(char* njk, const Ubranie &u);
    char* getNaJakaOkazje() {return naJakaOkazje;}
    void setNaJakaOkazje(char* njk) {naJakaOkazje=njk;}
    friend ostream & operator<<(ostream &, const UbranieWyjsciowe &);
    virtual void dane();
    virtual void wypisz();

};

#endif 

**plik klasa.cpp
**

#include "ubranie.h"
#include <iostream>

using namespace std;

void AbstrUbranie::wypisz()
{
    cout<<nazwa<<", "<<material<<", "<<wzrost;
}



int Ubranie::ilosc=0;
void Ubranie::wypisz()
{
    cout<<nazwa<<", "<<material<<", "<<wzrost;
}

void Ubranie::dane()
{
    cin>>nazwa;
    cin>>material;
    cin>>wzrost;
}


Ubranie::Ubranie()
{
    nazwa= new char [1];
    nazwa[0]='\0';
    material =new char[1];
    material[0]='\0';
    wzrost=0;
    ilosc++;
}

Ubranie::~Ubranie()
{
delete[] nazwa;
delete[] material;
ilosc--;
}

Ubranie::Ubranie(const char* _nazwa, const char* _material, int _wzrost)
{
    nazwa= new char [strlen(_nazwa)+1];
    strcpy(nazwa,_nazwa);
    material= new char [strlen(_material)+1];
    strcpy(material, _material);
    wzrost=_wzrost;
    ilosc++;
}

Ubranie::Ubranie(const Ubranie &u)
{
    nazwa= new char[strlen(u.nazwa)+1];
    strcpy(nazwa,u.nazwa);
    material= new char[strlen(u.material)+1];
    strcpy(material,u.material);
    wzrost=u.wzrost;
    ilosc++;
}

UbranieSportowe::UbranieSportowe(char* ds, const char* naz, const char* mat, int wzrost):Ubranie(naz,mat,wzrost)
{
    doJakiegoSportu=ds;
}

UbranieSportowe::UbranieSportowe(char* ds, const Ubranie &u): Ubranie(u)
{
    doJakiegoSportu=ds;
}

UbranieWyjsciowe::UbranieWyjsciowe(char* njk, const char* naz, const char* mat, int wzrost):Ubranie(naz,mat,wzrost)
{
    naJakaOkazje=njk;
}

UbranieWyjsciowe::UbranieWyjsciowe(char* njk, const Ubranie &u)
{
    naJakaOkazje=njk;
}

void UbranieSportowe::dane()
{
    cin>>doJakiegoSportu;
    cin>>nazwa;
    cin>>material;
    cin>>wzrost;
}

void UbranieWyjsciowe::dane()
{
    cin>>naJakaOkazje;
    cin>>nazwa;
    cin>>material;
    cin>>wzrost;
}

void UbranieSportowe::wypisz()
{
    cout<<doJakiegoSportu<<", "<<nazwa<<", "<<material<<", "<<wzrost;
}

void UbranieWyjsciowe::wypisz()
{
    cout<<naJakaOkazje<<", "<<", "<<nazwa<<", "<<material<<", "<<wzrost;
}

Ubranie & Ubranie::operator=(const Ubranie &u)
{
if (this==&u)
//return *this;
delete[] nazwa;
delete[] material;
nazwa=new char[strlen(u.nazwa)+1];
material=new char[strlen(u.material)+1];
strcpy(nazwa,u.nazwa);
strcpy(material, u.material);
return *this;
}


int Ubranie::iloscUbran()
{
    return ilosc;
}

ostream & operator<<(ostream &os, const Ubranie &u)
{
        os <<u.nazwa << " " << u.material << "Wzrost: " <<u.wzrost;
    return os;


}

ostream & operator<<(ostream &os, const UbranieSportowe &u)
{
        os <<u.doJakiegoSportu<< " " <<u.nazwa << " " << u.material << " Wzrost: " <<u.wzrost;
    return os;
}

ostream & operator<<(ostream &os, const UbranieWyjsciowe &u)
{
        os <<u.naJakaOkazje<< " " <<u.nazwa << " " << u.material << " Wzrost: " <<u.wzrost;
    return os;
} 

main.cpp

#include <iostream>
#include "ubranie.h"

#include <cstring>

using namespace std;

int main()
{
Ubranie u2("rekawice", "skorzane",175);
UbranieSportowe u3("bieganie" ,"spodnie", "dres", 200);
cout << u2 << "\n";
cout << u3 <<"\n";
UbranieSportowe u4("narty", u2);
cout << u2 << "\n" << u4 << "\n";

 cout<<"\n ---------------------------- \n"<<endl;

UbranieSportowe ubs;
UbranieWyjsciowe ubo;

Ubranie* ub1 = &ubs;
Ubranie* ub2 = &ubo;

ub1->wypisz();
cout<<"\n";
ub2->wypisz();

return 0;
}
 

Oczywiście te 3 pliki wchodzą w skład jednego projektu. Nie jestem pewny czy klasę abstrakcyjną mam dobrze, ale w tym programie chodzi głównie o funkcje wirtualne i jak je wywoływać, aby działały poprawnie?

0
int main()
  {
   AbstrUbranie &Tb[]=
     {
      *(Ubranie("rekawice", "skorzane",175)),
      *(UbranieSportowe("bieganie" ,"spodnie", "dres", 200)),
      *(UbranieSportowe("narty" ,"buty", "plastik", 16)),
     };
   for(size_t i=0;i<sizeof(Tb)/sizeof(*Tb);++i)
     {
      Tb[i].wypisz();
      cout<<endl;
     }
   return 0;
  }
0

Rozumiem, że chcesz, żeby class AbstrUbranie była klasą abstrakcyjną? Ale żeby klasa była abstrakcyjna musi mieć przynajmniej jedną funkcję czysto wirtualną, np. virtual void dane() = 0; I nie możesz już potem tworzyć obiektu tej klasy.

0

@tubbs, w tym kodzie jest wiele poważniejszych bzdur niż nazwa klasy nie odpowiadająca rzeczywistości. :D

0
class A {
    public:
        virtual void f() { cout << "A"; }
};

class B: public A {
    public:
        void f() { cout << "B"; }
};


class C {
    public:
        void f() { cout << "C"; }
};

class D: public C {
    public:
        void f() { cout << "D"; }
};

przeanalizuj rzutujac w gore, ot cala filozofia.

0

po co w C++ używać zwykłych stringów z klasycznego C i się męczyć ze kopiowaniem skoro można użyć std::string??

0

@robcio, aby pokazać prowadzącemu że się ma jakieś pojęcie o przydzielaniu pamięci.

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