Класс производного шаблона C ++: член экземпляра, защищенный от доступа

У меня есть базовый класс шаблона и производный класс шаблона. У производного метода есть перегруженный метод с аргументом, который содержит ссылку на объект того же типа, что и базовый класс. Если бы это не был шаблонный класс, я бы сделал производный класс другом базового класса, чтобы в этом случае я мог получить доступ к защищенным членам базы, но как мне это сделать с помощью шаблонов?

template <typename T>
class base
{
    // If this wasn't a template class, I would have done this:
    // friend class derived;

public:
    base(T val)
        : val_(val)
    {
    }

    virtual void assign(const base<T>& other)
    {
        val_ = other.val_;
    }

protected:
    T val_;
};

template <typename T>
class derived : public base<T>
{
public:
    derived(T val)
        : base<T>(val)
    {
    }

    virtual void assign(const base<T>& other)
    {
        this->val_ = other.val_; // error: ‘int base<int>::val_’ is protected
    }
};

int main()
{
    derived<int> a(5);
    derived<int> b(6);
    b.assign(a);
    return 0;
}

person Tom    schedule 12.09.2013    source источник
comment
Почему не просто base<T>::assign(other);? Почему derived отвечает за управление состоянием base? В любом случае, если вы действительно хотите использовать friend, вы можете: template <typename T> class derived; template <typename T> class base { friend class derived<T>; };   -  person Igor Tandetnik    schedule 12.09.2013
comment
Возможный дубликат этого: stackoverflow.com/questions/4010281/   -  person Colin Basnett    schedule 12.09.2013
comment
cmbasnett: Нет, на самом деле я прочитал этот конкретный вопрос до того, как опубликовал и попробовал то, что было предложено там, но этот случай другой. Я пытаюсь получить доступ к защищенному члену другого экземпляра.   -  person Tom    schedule 12.09.2013
comment
Игорь, спасибо за предварительное объявление класса шаблона и объявление его как друга, похоже, помогает.   -  person Tom    schedule 12.09.2013


Ответы (1)


Зачем нужен virtual? В вашем примере derived::assign() делает то же самое, что и base::assign().

class base
{
    ...
    public:
    ...
    void assign(const base<T>& other)
    ...
}
derived<int> b(6);
b.assign(a); //calls base<int>::assign(..)

Если derived нужно еще поработать в assign(..), используйте base<T>::assign(other); по предложению Игоря Тандетника. Нет необходимости использовать friend.

person John_West    schedule 27.11.2015