Dziedziczenie z klasy abstrakcyjnej szablonu

Nov 24 2020

Mam taką strukturę kodu:

  • Klasa abstrakcyjna A (ma czystą metodę wirtualną)
  • Szablon klasy B, który dziedziczy po A
  • Szablon klasy C, który dziedziczy po B.
class A
{
protected:
    int u;
    int z;

public:
    A(int uu,
      int zz)
    :u(uu),
     z(zz)
    {};

    int get() const
    {
    return u;
    };

    virtual void blah() = 0;
};

template <class T>
class B : public A
{
protected:
    std::vector<T> xxxx;
public:
    B(int uu,
      int zz,
      int bbb)
    :A(uu,
       zz)
    {
    for(size_t i = 0; i < bbb; i ++)
        xxxx[i] = 0;
    };

    virtual void blah()
    {
    u = u + 1;
    };
};

template <class T>
class C : public B<T>
{
protected:
    int qrqr;

public:
    C(int uu,
      int zz,
      int bbb,
      int qrqrqr)
    :B<T>(uu,
          zz,
          bbb),
     qrqr(qrqrqr)
    {
    };

    virtual void blah()
    {
    u = u + qrqr;
    };
};

Podczas kompilacji pojawia się ten błąd:

 
error: 'u' was not declared in this scope
    at line:  u = u + qrqr;

Chociaż ujest wyraźnie elementem C, ponieważ A jest podstawą od C do B.

Czytałem tutaj: Dziedziczenie szablonów klas C ++, że właściwym sposobem dziedziczenia z szablonu klasy jest albo specjalizacja klasy, albo dziedziczona klasa jako szablon i oto co tutaj zrobiłem. Kompilator i tak nie narzeka na to. Czy to możliwe, ponieważ A jest klasą abstrakcyjną?

Co zrobiłem źle?

Dzięki!

Odpowiedzi

1 AmiTavory Nov 24 2020 at 16:08

To jest problem z niezależną nazwą - element członkowski, do którego się odwołujesz, nie zależy od parametru szablonu. Kompilator nie szuka w zależnych klasach bazowych (takich jak B<T>) podczas wyszukiwania niezależnych nazw (takich jak u).

Możesz go rozwiązać za pomocą

this->u = this->u + qrqr;

który określa kompilator, o którym umyślisz.

( coliru )

Istnieją co najmniej dwa inne sposoby, wywołanie B<T>::ulub wpisanie using B<T>::u;funkcji przed tą linią.

Przeczytaj więcej na ten temat tutaj .