从模板化的类赋值操作符访问私有成员变量

Accessing private member variables from a templated class assignment operator

本文关键字:访问 成员 变量 赋值操作符      更新时间:2023-10-16

我有一个模板化的容器类。我重载了赋值操作符,使得派生类型也可以赋值。

我的问题是,当类型不相同时,我无法访问容器类的私有成员。获得访问权限的最佳途径是什么?成员变量不能通过公共getter来访问。谢谢!

示例代码:

// 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;
}

由于您想要访问用不同类型实例化的模板类的私有成员,因此您必须使其他模板作为模板类的朋友,如:

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

注意,如果TU是不同的类型,那么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;
};

那么这里只有BA的朋友。A不是B的朋友。他们不是"彼此的朋友"B可以访问A的私有成员,而A不能访问B的私有成员。

第一个操作符可以工作,因为访问是类作用域而不是对象作用域。这意味着你可以跨同一个类的实例访问私有成员。

要访问不同类的私有成员而不使用getter或setter,你需要使你的类与另一个类成为朋友。

其他方法涉及hack,直接访问内存并且不可移植