Доступ к частным переменным-членам из шаблонного оператора присваивания класса

У меня есть класс контейнера, который templatized. Я перегружаю оператор присваивания таким образом, что производные типы также могут быть назначены.

Моя проблема в том, что когда тип не совпадает, я не могу получить доступ к закрытым членам класса контейнера. Каков наилучший подход к получению доступа? Переменные-члены не могут быть доступны через публичные геттеры. Спасибо!

Пример кода:

// Note: var is private

template <class T>
Container<T>& Container<T>::operator=(const Container<T>& rhs) {
   if(*this != rhs) var = rhs.var; // works for same type
   return *this;
}

template <class T>
template <typename U>
Container<T>& Container<T>::operator=(const Container<U>& rhs) {
   if(*this != rhs) var = rhs.var; // does NOT work for different types
   return *this;
}

Ответ 1

Поскольку вы хотите получить доступ к закрытым членам класса шаблонов, созданных с помощью разных типов, вы должны сделать другие шаблоны в качестве друга класса шаблона следующим:

template <class T>
class Container
{
      template<class U> 
      friend class Container;

};

Обратите внимание, что если T и U - разные типы, то Container<T> и Container<U> - два совершенно разных класса; невозможно получить доступ к частным членам другого, если вы не делаете друга другим.

Также обратите внимание, что в приведенном выше коде все экземпляры шаблона класса являются друг другу. То есть, если вы создаете экземпляр с помощью char, int, short, тогда

  • Container<int> будет другом как Container<char>, так и Container<short>.
  • Container<char> будет другом как Container<int>, так и Container<short>.
  • Container<short> будет другом как Container<int>, так и Container<char>.

Интересная фраза здесь: "друг друг друга" . Обычно этого не происходит. Например, если у вас есть такой класс:

class A
{
   friend class B;
};

Тогда здесь только B является другом A. A НЕ является другом B. Они НЕ "друг друг друга". B может получить доступ к частным членам A, но A не может получить доступ к закрытым членам B. В этом разница между этим классом и классом выше.

Ответ 2

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

Чтобы получить доступ к частному члену из другого класса без использования геттеров или сеттеров, вам нужно сделать своих друзей класса с другим классом.

Другие способы включают хаки, прямой доступ к памяти и не переносимые.