Herdando da classe abstrata do modelo

Nov 24 2020

Eu tenho esta estrutura de código:

  • Uma classe abstrata A (tem um método virtual puro)
  • Um modelo de classe B que herda de A
  • Um modelo de classe C que herda de 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 eu compilo, recebo este erro:

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

Embora useja claramente um elemento de C porque A é uma base de C a B.

Eu li aqui: Herança de template de classe C ++ que a maneira correta de herdar de template de classe é especializar a classe ou ter a classe herdada como template e isso é o que eu fiz aqui. O compilador não parece reclamar disso de qualquer maneira. Será que A é uma classe abstrata?

O que eu fiz errado?

Obrigado!

Respostas

1 AmiTavory Nov 24 2020 at 16:08

Este é um problema com um nome não dependente - o membro ao qual você está se referindo não depende do parâmetro do modelo. O compilador não olha em classes base dependentes (como B<T>) ao procurar nomes não dependentes (como u).

Você pode resolver isso usando

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

que especifica para o compilador que uvocê quer dizer.

( coliru )

Existem pelo menos duas outras maneiras, chamando B<T>::uou escrevendo using B<T>::u;na função antes desta linha.

Leia mais sobre isso aqui .