我在c ++中有一个嵌套类,必须是公共的。但我需要一些外部世界可见的方法,其余的只能 到嵌套类。那就是:
class set {
public:
class iterator {
innerMethod();
public:
outerMethod();
}
}
我希望能够为set使用innerMethod()编写一个方法。如果我把它公之于众,我也可以从外面访问它,这是我绝对不想要的。有没有办法在不做“朋友类集”的情况下做到这一点?
提前致谢!
答案 0 :(得分:2)
没有使用friend
关键字,您可以做到这一点。
你在评论中说:
在我目前的编程课程中 据说,使用'朋友'是 不明智和普遍考虑 大多数情况下“糟糕的编程” 除非真的没有别的办法 周围。所以我试着避免它 尽可能多。
friend
打破了封装,也许这就是为什么你的班级老师说这是错误的编程。 但是成员函数也破坏了封装,那你为什么要使用它们呢?为什么不避免它们呢? friend
以与成员函数相同的方式打破封装; 因此,如果您在需要时使用成员函数时感觉很舒服,那么您应该在需要的时候使用friend
以及会很舒服。因为某种原因,它们都存在于C ++中!
class set {
public:
class iterator
{
friend class set; //<---- this gives your class set to access to inner methods!
void innerMethod(){}
public:
void outerMethod(){}
};
iterator it;
void fun()
{
it.innerMethod();
it.outerMethod();
}
};
答案 1 :(得分:1)
不,我认为还有其他非hacky方法,但使用friend
- 指令。
friend
存在就是出于这种目的,你为什么要避免它呢?
答案 2 :(得分:1)
试着问:有没有办法添加2个数字而不添加它们? 对不起,如果我很苛刻,但朋友类就是这样......
答案 3 :(得分:1)
是的。
我一直试图提倡这个方法一段时间,基本的想法是使用Key
类。
虽然这实际上并没有删除 friend
的使用,但它确实减少了公开的实现细节集。
class set;
// 1. Define the Key class
class set_key: noncopyable { friend class set; set_key() {} ~set_key() {} };
class set
{
// 2. Define the iterator
class iterator
{
public:
void public_method();
void restricted_method(set_key&);
}; // class iterator
}; // class set
现在,restricted_method
是公开的,因此set
不需要对iterator
的任何特殊访问权限。但是,它的使用仅限于那些能够传递set_key
实例的人......而且只有set
才能构建这样的对象。
请注意,set
实际上可能会将set_key
对象传递给其信任的其他人。这是传统意义上的关键:如果你把公寓的钥匙交给某人,它可能会委托给另一个人。但是由于密钥类的语义(不可复制,只有set
可以构造并销毁它),这通常仅限于key
对象范围的持续时间。
请注意,恶意黑客总是可能的,即*((set_key*)0)
。这个方案可以保护Murphy,而不是Machiavelli(无论如何都不可能在C ++中)。
答案 4 :(得分:0)
您可以这样做:
课程集
{
public:
class iterator
{
protected:
iterator(){};
virtual ~iterator(){};
public:
//outer world methods...
};
private:
class privateIterator : public iterator
{
public:
privateIterator(){};
~privateIterator(){}
//inner methods;
};
public:
iterator* CreateIterator()
{
return new privateIterator();//this is used to be sure that you only create private iterator instances
}
};
我不知道这是否是正确的答案,但现在它确实使用了朋友的关键工作,它隐藏了一些方法。唯一的问题是你不能声明privateIterator而且你总是必须使用CreateIterator来创建一个实例......