Wywoływanie metody klasy abstrakcyjnej.

0

Witam. Stworzyłem taką oto klasę abstrakcyjną:

 
#ifndef ABSTRACT_DMA_H_
#define ABSTRACT_DMA_H_
#include <iostream>

class abstractDMA
{
private:
    char * label;
    int rating;
protected: // moze sie przydac do metody View
	const char * Label() {return label;}
	const int Rating() {return rating;}
public:
    abstractDMA(const char * l = "brak", int r = 0);
    abstractDMA(const abstractDMA & rs);
    abstractDMA & operator=(const abstractDMA & rs);
	friend std::ostream & operator<<(std::ostream & os, const abstractDMA & rs);
    virtual ~abstractDMA() = 0;
    virtual void View() const = 0;
};
#endif // ABSTRACT_DMA_H_

Oraz dziedziczącą z niej, klasę pochodną:

 
#include "abstractDMA.h"

class hasDMA : public abstractDMA
{
private:
    char * style;
public:
    hasDMA(const char * s = "brak", const char * l = "brak", int r = 0);
    hasDMA(const char * s, const abstractDMA & rs);
    hasDMA(const hasDMA & hs);
    virtual ~hasDMA() { delete [] style; }
    hasDMA & operator=(const hasDMA & rs);
    friend std::ostream & operator<<(std::ostream & os, const hasDMA & rs);
    char * getstyle() { return style; }
    virtual void View() const;
};
 

Metoda View() klasy abstrakcyjnej:

void abstractDMA::View() const
{
    std::cout << "Wywolano metode View()" << std::endl;
    std::cout << "Etykieta: " << label << std::endl;
    std::cout << "Klasa: " << rating << std::endl;
}

Metoda View() klasy pochodnej:

void hasDMA::View() const
{
    abstractDMA::View();
    std::cout << "Styl: " << style << std::endl;
}

Po uruchomieniu programu mam problem z poprawnym wyświetleniem "stylu" tj:
user image

0

Pokaż kod, gdzie alokujesz pamięć dla tablicy style oraz zapisujesz jakieś dane tam.

Poza tym odnoszę wrażenie, że możesz mieć wyciek związany z label, bo gdzie sprzątasz tę tablicę?

0

Label oczywiście sprzątam. Dopisałem osobno i mogło to wprowadzić w błąd :)

abstractDMA::~abstractDMA()
{
    delete [] label;
}

Style alokuję zależnie od konstruktora, ale moja ogólna koncepcja wygląda tak:

style = new char [std::strlen(s) + 1];
std::strcpy(style, s);

np.

hasDMA::hasDMA(const hasDMA & hs) : abstractDMA(hs)
{
    style = new char [std::strlen(hs.style) + 1];
    std::strcpy(style, hs.style);
}
1

Po pierwsze powiedz mi, dlaczego używasz char* zamiast std::string?
Po drugie łatwo sprawdzić, co jest w style przed wypisaniem.

void hasDMA::View() const
{
    abstractDMA::View();
    cout << "DEBUG. style size: " << strlen(style) << endl;
    cout << "Styl: " << style << std::endl;
}

Zakładając, że wcześniej zarezerwowałeś pamięć i wpisałeś poprawny C-string (dlatego std::string ułatwiałby życie)

0

Zgadzam się co do string, jednak jest to zadanie z książki, którą przerabiam i autor narzucił taki typ.

Edit: style size 0 ;/ wydaje mi się, że dobrze zaalokowałem. Zaraz wrzucę kod.

Edit2:

#include "hasDMA.h"
#include <cstring>

hasDMA::hasDMA(const char * s, const char * l, int r) : abstractDMA(l,r)
{
    style = new char [std::strlen(s) + 1];
    std::strcpy(style, s);
}

hasDMA::hasDMA(const char * s, const abstractDMA & rs) : abstractDMA(rs)
{
    style = new char [std::strlen(s) + 1];
    std::strcpy(style, s);
}

hasDMA::hasDMA(const hasDMA & hs) : abstractDMA(hs)
{
    style = new char [std::strlen(hs.style) + 1];
    std::strcpy(style, hs.style);
}

hasDMA & hasDMA::operator=(const hasDMA & rs)
{
    if (this == &rs) return *this;
    abstractDMA::operator=(rs);
    delete [] style;
    style = new char [std::strlen(rs.style) + 1];
    std::strcpy(style, rs.style);
    return *this;
}

std::ostream & operator<<(std::ostream & os, const hasDMA & rs)
{
    os << (const abstractDMA &) rs;
    os << "Styl: " << rs.style << std::endl;
    return os;
}

void hasDMA::View() const
{
    abstractDMA::View();
    std::cout << "DEBUG. style size: " << std::strlen(style) << std::endl;
    std::cout << "Styl: " << style << std::endl;
}
2

Przed każdą alokacją (w hasDMA) sprawdź jaki jest rozmiar i zawartość stringa, którego chcesz skopiować.

0

Dzięki. Okazało się, że problem był trywialny...
W mainie miałem kod:

case '3':
            char temp_style[100];
            cout << "Podaj styl: ";
            cin.getline(temp_style,100);
            p_clients[i] = new hasDMA(temp_style, temp_label, temp_rating);
            break;

Zamieniłem na:

case '3':
            char temp_style[100];
            cout << "Podaj styl: ";
            cin >> temp_style;
            p_clients[i] = new hasDMA(temp_style, temp_label, temp_rating);
            break;

i jest ok ;)

0
mariusz_s napisał(a):

Witam. Stworzyłem taką oto klasę abstrakcyjną:
… … …
Metoda View() klasy abstrakcyjnej:
… … …
No to jest abstrakcyjna czy nie?

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