Ereditando da template abstract class

Nov 24 2020

Ho questa struttura di codice:

  • Una classe A astratta (ha un metodo virtuale puro)
  • Un modello di classe B che eredita da A
  • Un modello di classe C che eredita da 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;
    };
};

Quando compilo ottengo questo errore:

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

Sebbene usia chiaramente un elemento di C perché A è una base da C a B.

Ho letto qui: Ereditarietà del modello di classe C ++ che il modo corretto di ereditare dal modello di classe è specializzare la classe o avere la classe ereditata come modello e questo è quello che ho fatto qui. Il compilatore non sembra lamentarsene comunque. Potrebbe essere perché A è una classe astratta?

Cos'ho fatto di sbagliato?

Grazie!

Risposte

1 AmiTavory Nov 24 2020 at 16:08

Questo è un problema con un nome non dipendente : il membro a cui ti riferisci non dipende dal parametro del modello. Il compilatore non cerca nelle classi di base dipendenti (come B<T>) quando cerca nomi non dipendenti (come u).

Puoi risolverlo usando

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

che specifica al compilatore cosa uintendi.

( coliru )

Ci sono almeno altri due modi, chiamando B<T>::uo scrivendo using B<T>::u;nella funzione prima di questa riga.

Per saperne di più qui .