Objective-C类别功能允许程序员添加未在原始类定义中定义的新方法.
我可以在C++上存档类似的功能(语言构造或某些技术)吗?
主要关注的是一致的方法调用语法(.或->运算符).
让我们考虑扩展以下类:
struct A {
int x, y;
A(int x, int y) : x(x), y(y) {}
};
Run Code Online (Sandbox Code Playgroud)
您可以从此类继承或编写包含此类实例的包装类.在大多数情况下,继承是要走的路,因为包装类不是 A而是包装(包含)A.
使用C++ 11移动语义,将实例A提升为子类B(继承A)将是高效的,并且不需要复制实例A:
class B : public A {
public:
B (A &&a) : A(a), someOtherMember(a.x + a.y) {}
// added public stuff:
int someOtherFunction() const { return someOtherMember; }
private:
// added private stuff:
int someOtherMember;
};
Run Code Online (Sandbox Code Playgroud)
完整代码示例:http://ideone.com/mZLLEu
当然,我说的功能是有点傻(和成员甚至更多,因为它不尊重创始成员的进一步变化x和y),但你应该得到什么,我想演示的想法.
注意构造函数B (A &&a),我称之为"提升构造函数"(这不是标准术语).通常,B (B &&b)是一个移动构造函数,它将提供的实例的内容移动到即将构造B的新B内容中.我使用移动语义将A(由另一个函数返回)的实例移动到超类A中B.
实际上,你可以促进A,B同时可以使用a B作为A.
与Soonts的回答相反,我的解决方案也适用于添加的虚拟表,因为它不依赖于不安全的指针转换.
另一个选项,可能不被某些人视为"干净"(尽管在我看来)但仍然完成同样的事情,是使用静态类.重要的是要记住,当我们创建一个成员函数时,幕后真正发生的是编译生成一个函数,其中对象(又名"this")是第一个参数.因此,我们可以做同样的事情来扩展我们的类的功能而不从它衍生出来.
class Something
{
public:
Something()
~Something()
}
// In objective-c you may call this category Something+Utils
class SomethingUtils
{
// You can use a pointer, or a reference here, your call.
static int GetSomethingElse(Something *something, int parameter);
}
Run Code Online (Sandbox Code Playgroud)
这将实现与类别相同的意图:扩展类对象的功能,而不必创建新的派生类.您将无法访问私有或受保护的成员函数和变量,但无论如何您都无法在objective-c中执行此操作,因此在该方面没有任何损失(如果您尝试使用私有或受保护的成员状态,则完全错过了类别的重点.你将无法使用.和 - >运算符,但在我看来,这比仅仅为了添加一些实用方法而导出新类型更好.