C++ 代理和 Borland C++ Builder 事件处理 - 第一部分






4.60/5 (6投票s)
描述了 Borland 如何通过 __closure 关键字绕过标准的 C++ 限制
引言
本文分为两个主要部分。
第一部分讨论标准的 C++ **成员函数指针 (MFP)**,它与普通函数指针不同。 它还说明了这些类型指针的限制,以及 Borland C++ Builder 如何通过其特殊的 MFP 类型 **__closure** 绕过这些限制。
第二部分展示了使用这种 MFP 的一个应用。 它详细解释了 Borland 如何使用他们自己的 MFP 类型来处理 Windows 事件,以及它与 MFC 风格或 Win32 API 风格相比有多么吸引人。
背景知识
我假设读者有足够的背景知识来使用 MFP。 我知道它的语法有点笨拙,但我没有详细解释。 相反,我使用注释来解释代码行的作用。
此外,我假设读者了解**继承**和**多态**。
第一部分 - 闭包:介绍
闭包是 C++ builder 中一个非常有用的特性。 为了说明这一点,我们首先来谈谈 C++ 中普通的成员函数指针。
尝试以下代码
#include <stdlib.h>
class Base{public:int baseFunc(int){}};
class Drvd:public Base{public:int drvdFunc(int){}};
class Alone{public:int aloneFunc(int){}};
//----------------------- Normal member-function-pointers ---------------
int main() {
int (Base::*funcPtr)(int); // MFP of type Base::*
funcPtr = &Drvd::baseFunc; // member-function pointed to
Drvd ob; // type of calling object
(ob.*funcPtr)(2); // calling of MFP is from here
system("pause");
return 0;
}
此代码展示了普通 C++ 成员函数指针 (MFP) 的行为。
正如我们所见,类型为 Base::*
的 MFP 可以指向以下内容
Base::baseFunc
- 可以从Base
/Drvd
类型的对象调用。Drvd::baseFunc
- 可以从Base
/Drvd
类型的对象调用。
Drvd::drvdFunc
Alone::aloneFunc
如果我们将 MFP 的类型更改为 Drvd::*
,情况将略有改变,可以指向
Base::baseFunc
- 可以从Drvd
类型的对象调用Drvd::baseFunc
- 可以从Drvd
类型的对象调用Drvd::drvdFunc
- 可以从Drvd
类型的对象调用
但是,它不能指向
Alone::aloneFunc
最后,如果我们的 MFP 类型为 Alone::*
,它只能指向
Alone::aloneFunc
- 可以从Alone
类型的对象调用
并且它不能指向
Base::baseFunc
Drvd::baseFunc
Drvd::drvdFunc
Borland 的 "__closure" 关键字
Borland 向该语言添加了一个新的关键字,以绕过标准 C++ 设置的限制。
这个关键字是 __closure
。
到目前为止,我们有三个限制:
- 类型为
Base
的 MFP 不能指向Drvd
的新(未继承)成员函数。 - MFP 不能指向继承层次结构之外的类中的任何成员函数,例如
Base
/Drvd
和Alone
。 - 我们不能使用对象名称将指针分配给我们的 MFP 中的成员函数,而必须使用完全限定的名称
Class::member
-function。 如果解决了这个问题会非常有用,因为对象可能会在运行时发生多态变化。
实际上,第一个和第二个限制非常相似。 换句话说,我们的目标是使任何 MFP 指向任何类中的任何成员函数,无论该类是否在继承层次结构中。
让我们看看 Borland 如何使用 __closure
关键字解决这个问题。
#include <stdlib.h>
class Base{public:int baseFunc(int){}};
class Drvd:public Base{public:int drvdFunc(int){}};
class Alone{public:int aloneFunc(int){}};
//---------------------- Borland's C++ Buildre's Closures ---------------
int main() {
int ( __closure *funcPtr)(int); // special MFP of type __closure
Drvd ob;
funcPtr = ob.drvdFunc; // member-function pointed to
funcPtr(2); // calling of closure is from here
system("pause");
return 0;
}
尝试将 funcPtr
指向任何成员函数并查看结果。 只需确保它具有相同的参数列表和相同的返回类型。
现在让我们看看解决第三个问题会多么有用。 查看以下代码
#include <iostream.h>
class Base{public:virtual int baseFunc(int){cout << "i am baseFunc in Base class\n" ; }};
class Drvd:public Base{public:int baseFunc(int)
{cout << "i am baseFunc in Drvd class\n" ; }};
//---------------------- Borland's C++ Buildre's Closures ---------------
int main() {
int ( __closure *funcPtr)(int); // special MFP of type __closure
Base *ob = new Base();
funcPtr = ob->baseFunc; // member-function pointed to
funcPtr(2); // calling of MFP is from here
delete ob;
ob = new Drvd(); // polymorphic behaviour
funcPtr = ob->baseFunc;
funcPtr(2);
delete ob; ob=NULL;
system("pause");
return 0;
}
这不是很棒吗? 谢谢 Borland。
在第二部分中再见。
历史
- 2009 年 11 月 26 日:首次发布