我目前正在寻找一种适当的方法来限制特定类型的类使用方法。更清楚的是,情况如下:
我有一个专门用于服务器网络的课程(让我们称之为ClientSession
)。客户端连接到服务器后,有30秒的时间进行身份验证,或者服务器将关闭连接。
身份验证由服务器上的另一个类处理(让我们称之为Authenticator
),这应该是警告' ClientSession
客户端验证成功,30秒计时器可以取消。
问题是,这需要Authenticator
来调用ClientSession
的公共方法。但是我不希望任何人都能调用这种方法。
总结一下,我希望Authenticator
成为唯一能够调用ClientSession::clientAuthSuccessful()
方法的类。
我已经研究过两件事:
Authenticator
能够通过朋友方法访问所有私有方法和属性或ClientSession
。还有其他方法可以有这样的特定限制吗?还是一个干净的选择?
答案 0 :(得分:2)
定义一个接口AuthenticatorListener
,其中定义了clientAuthSuccessful()
方法(纯虚拟)。
让ClientSession
私下继承AuthenticatorListener
并私下实施该方法。
然后将ClientSession
实例传递给Authenticator
。
现在没有其他类可以访问该方法。并且Authenticator
未与ClientSession
耦合,只与适当隔离的界面耦合。
答案 1 :(得分:1)
这样做没有干净的方法,没有。您可以使用朋友类或公共方法。
没有干净的方式并不意味着不可能。我永远不会写这样的代码,你也不会这样做,但以下内容确实符合要求:
class Lock
{
friend class B;
private:
Lock() {};
};
class A
{
public:
A() {}
void foo(Lock x){}
};
class B
{
void foo()
{
Lock l;
A a;
a.foo(l);
}
};
由于class B
是唯一可以创建Lock
个实例的类,而A::foo
需要Lock
个实例作为参数,因此只能由{{1}调用}}
不要这样做。我建议在标题中添加注释和文档。
答案 2 :(得分:1)
有一种更简单的方法。只需将一些特殊用途的代码从ClientSession
传递到Authenticator
即可。您可以使用函数指针,函数对象或lambda函数来实现此目的。
class ClientSession
{
public:
void startSession ( Authenticator& authenticator )
{
// pass function pointer to method to call when
// the timeout for authentication has elapsed.
authenticator.start(this, &ClientSession::warnThat30SecsHasPassed);
// alternative syntax, using new lambda function syntax,
// which will end up reducing coupling between the two classes.
authenticator.start([this](){ warnThat30SecsHasPassed() });
}
private:
void warnThat30SecsHasPassed () { ... }
};
class Authenticator
{
public:
// classic way.
void start ( ClientSession * session, void(ClientSession::*callback)() );
// using new syntax.
void start ( std::function<void()> callback );
}
答案 3 :(得分:0)
您可以创建ClientSession
朋友和朋友Authenticator
。
答案 4 :(得分:0)
当遇到问题时,人们经常会想到如何解决问题,并将精力放在如何实施该解决方案上。有时,更好地重新审视问题并考虑其他解决方案。
例如,不要让Authenticator
尝试通知传递给它的ClientSession
(或者更好的方法是,通过调用传递给它的某种回调 ),让ClientSession
(或其他一些对象/线程)调用像Authenticator::waitForAuthentication(int timeout)
这样的方法呢?
编辑:我想我会详细说明回调概念。关键是Authenticator
不需要知道ClientSession
类来完成它的工作;它只需要知道调用某个函数或其他可调用函数。
因此,您编写Authenticator
以使方法接受正确签名的某个std::function
对象,并使ClientSession
(或其他)创建合适的内容以传入。它可能是一个类似于Luchian Grigore所建议的特殊功能对象。也许它是一个稍微更通用的对象,或者可能是通过引用ClientSession
对象的私有部分来初始化的对象。或者它是一个lambda,如果你可以使用C ++ 11。
那就是说,我怀疑使用waitForAuthentication
方法(或完全不同的方法)很可能是你真正想要的应用程序。