Definicja pochodnej do metody czysto wirtualnej

0

Może ktoś obeznany ze standardem będzie potrafił wyjaśnić czemu taki cudo nie linkuje się (zarówno w dev-cpp jak i Visual). (undefined reference A::~A())

class A{
public:
	virtual ~A()=0;
};
class B:public A{
public:
	~B();
};
B::~B(){}

Nie znalazłem odpowiedzi w necie, wszystkie opracowania o klasach abstrakcyjnych itp. rozważają jedynie definicję metody ~B() inline, czyli wewnątrz klasy. i to faktycznie działa.

0

Napisz kod destruktora klasy A (choćby i pusty). Przecież destruktor i tak zostanie wywołany, jego implementację trzeba dostarczyć zawsze, nawet, jeśli jest czysto wirtualny.

0
Fanael napisał(a)

Napisz kod destruktora klasy A (choćby i pusty).

Owszem, sprawdzałem, że wtedy działa i w moim programie w ten sposób ominąłem problem. Zastanawia mnie tylko czysto teoretyczne pytanie dlaczego tak muszę robić.

Fanael napisał(a)

Przecież destruktor i tak zostanie wywołany,

Problem dotyczy wszystkich metod, nie tylko destruktora, więc argument, że i tak zostanie wywołany odpada.

Fanael napisał(a)

jego implementację trzeba dostarczyć zawsze, nawet, jeśli jest czysto wirtualny.

Według mojej dotychczasowej wiedzy na tym polegała czysta wirtualność, że nie trzeba implementować, bo każda funkcja pochodna ma swoją wersję i funkcja bazowa zazwyczaj nie będzie wykonywana.
Zresztą jeśli destruktor ~B() zaimplementować inline, implementacja ~A() okazuje się być niepotrzebna.</quote>

0
Gość_Szymon napisał(a)
Fanael napisał(a)

jego implementację trzeba dostarczyć zawsze, nawet, jeśli jest czysto wirtualny.

Według mojej dotychczasowej wiedzy na tym polegała czysta wirtualność, że nie trzeba implementować, bo każda funkcja pochodna ma swoją wersję i funkcja bazowa zazwyczaj nie będzie wykonywana.
</quote>

Ale destruktor jest w tym przypadku wyjątkowy.

0

OK, macie rację.
Pisząc

Gość_Szymon napisał(a)

Problem dotyczy wszystkich metod, nie tylko destruktora,

pomyliłem się, chociaż wydawało mi się, że to sprawdziłem dość dokładnie. Dotyczy to tylko destruktora.
Jednak nie do końca jest tak, że

Fanael napisał(a)

jego implementację trzeba dostarczyć zawsze, nawet, jeśli jest czysto wirtualny.

poniższy kod kompiluje się (co oczywiście nie znaczy, że jest poprawny), mimo, że nie ma implementacji destruktora ~A().

class A{
public:
        virtual void f()=0;
        virtual ~A()=0;
};
//A::~A(){}
class B:public A{
public:
        void f(){};
        ~B(){};
};
//B::~B(){}
//void B::f(){}

Jeżeli jednak którakolwiek metoda z klasy B przestaje być inline destruktor ~A() staje się niezbędny.
Czy ta niekonsekwencja jest zgodna z zasadami C++?

0

U mnie się poprawnie kompiluje, ale nie chce się zlinkować (słusznie zresztą)...

struct A { virtual ~A()=0; };
struct B : A { ~B() {} };
int main()
{
  B b;
  A* a = new B;
  delete a;
}
0

no tak, nie sprawdziłem czy po stworzeniu obiektu nadal działa, a to by mi wiele wyjaśniło.
Dzięki.

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