Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

czy ręczne wywołanie destruktora musi być tutaj obowiązkowe?

Ostatnio zmodyfikowano 2017-06-06 09:14
Autor Wiadomość
robaczek122
Temat założony przez niniejszego użytkownika
czy ręczne wywołanie destruktora musi być tutaj obowiązkowe?
» 2017-06-05 20:56:07
C/C++
#include "stdafx.h"
#include <iostream>
using namespace std;

class PolecenieInterface
{
public:
    virtual ~PolecenieInterface()
    {
        cout << "destruktor PolecenieInterface" << endl;
    }
    virtual void wykonaj() = 0;
};
class Polecenie1
    : public PolecenieInterface
{
public:
    ~Polecenie1()
    {
        cout << "destruktor Polecenie1" << endl;
    }
    virtual void wykonaj() override
    {
        cout << "polecenie 1" << endl;
    }
};
class Polecenie2
    : public PolecenieInterface
{
public:
    ~Polecenie2()
    {
        cout << "destruktor Polecenie2" << endl;
    }
    virtual void wykonaj() override
    {
        cout << "polecenie 2" << endl;
    }
};

class PrzyciskInterface
{
public:
    PrzyciskInterface( PolecenieInterface * p )
    {
        ppolecenie = p;
    }
    virtual ~PrzyciskInterface()
    {
        cout << "destruktor PrzyciskInterface" << endl;
    }
    void deletePolecenieInterface()
    {
        cout << "wywolaj deletePolecenieInterface" << endl;
        ppolecenie->~PolecenieInterface();
    }
    void wykonaj()
    {
        ppolecenie->wykonaj();
    }
    PolecenieInterface * ppolecenie = nullptr;
};
class Przycisk1
    : public PrzyciskInterface
{
public:
    Przycisk1( PolecenieInterface * p )
        : PrzyciskInterface( p )
    {
    }
    ~Przycisk1()
    {
        cout << "destruktor Przycisk1" << endl;
    }
};


int main()
{
    PrzyciskInterface * przycisk1 =( new Przycisk1( new Polecenie1 ) );
    //PrzyciskInterface * przycisk2 = (new Przycisk1(new Polecenie2));
    przycisk1->wykonaj();
    //przycisk2->wykonaj();
    przycisk1->deletePolecenieInterface();
    delete przycisk1;
    //delete przycisk2;
   
    return 0;
}
Napisałem coś w rodzaju wzorca projektowego "polecenie".
Zastanawiam się jak będzie wyglądało poprawne zwolnienie pamięci przy takim zadeklarowaniu wskaźnika przycisk1.
Skoro mam:
C/C++
PrzyciskInterface * przycisk1 =( new Przycisk1( new Polecenie1 ) );
przycisk1->deletePolecenieInterface(); //czy to jest obowiazkowe?
to czy muszę wywoływać funckję do recznej destrukcji obiektu, który stworzył się podczas tworzenia argumentu konstruktora (new Polecenie1)?
P-162101
1aam2am1
» 2017-06-05 21:34:35
Powinieneś w odpowiednim miejscu wywołać delete polecenie(ktore utworzyles z new)
P-162107
pekfos
» 2017-06-06 01:40:54
Ręczne wywołanie destruktora jest tutaj błędne. Co zaalokowałeś przez new musisz zwrócić przez delete. Destruktor jest wywoływany automatycznie przy zwalnianiu pamięci.
Istnieje tylko jeden przypadek, w którym ręcznie wywołuje się destruktor i jest na tyle specyficzny, że sam na niego przypadkiem nie wpadniesz.
P-162124
robaczek122
Temat założony przez niniejszego użytkownika
» 2017-06-06 07:19:49
Czy w takim razie, przy tak zapisanej linii kodu, jak poniżej:
C/C++
PrzyciskInterface * przycisk1 =( new Przycisk1( new Polecenie1 ) );

Poprawnym rozwiązaniem będzie dodanie metody wewnątrz PrzyciskInterface usuwającej to co jest pod wskaźnikiem (?):
C/C++
void deletePolecenieInterface()
{
    cout << "wywolaj deletePolecenieInterface" << endl;
    delete ppolecenie; //zamiast wywolywania destruktora
}

Z drugiej strony bardzo nieelegancko mi to wygląda.
P-162125
pekfos
» 2017-06-06 09:14:05
Po co to jest w osobnej metodzie? Wrzuć do destruktora.
P-162126
« 1 »
  Strona 1 z 1