我有一个模板化的容器类。我正在重载赋值运算符,以便也可以赋值派生类型。
我的问题是,当类型不一样时,我无法访问容器类的私有成员。获得访问权限的最佳方法是什么?无法通过公共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;
}
答案 0 :(得分:20)
由于您要访问使用不同类型实例化的模板类的私有成员,您必须将其他模板作为模板类的朋友:
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
的私人成员。 这是此类与上面的模板类之间的差异。
答案 1 :(得分:1)
第一个运算符起作用,因为访问是类范围而不是对象范围。这意味着您可以跨同一类的实例访问私有成员。
要在不使用getter或setter的情况下访问其他类的私有成员,您需要让您的班级成为其他班级的朋友。
其他方式涉及黑客攻击,直接访问内存并且不可移植。