据我所知,C ++不像ObjC那样具有向现有类中添加方法的机制(例如QString,但请不要专注于Qt函数这一事实)。我们假设这些新方法不需要任何新的成员变量。相反,唯一的选择是创建一个继承A的包装器类(例如KString),并添加所需的方法(例如toFoo())。
但是,这需要在要使用新方法的任何地方进行修改,例如
static_cast<KString*>(ptrToQStringInstance)->toFoo()
但是,如果有很多类似的地方,您希望能够在相关文件中使用#define QString KString
(或进行等效的搜索/替换)。
当然,您将遇到类似“无法从[const] QString到[const] KString的可行转换”之类的错误,您必须为其添加一个复制构造函数,如
inline KString(const QString &that)
{
*(static_cast<QString*>(this)) = that;
}
// add an assignment operator for good measure too
inline KTEStringView &operator=(const QString &other) Q_DECL_NOTHROW
{
*(static_cast<QString*>(this)) = other;
return *this;
}
我的问题:
-是否存在必须通过这种方式实现(重写)的定义良好且有限的方法集(独立于父类),或者您是否正在考虑覆盖所有返回QString的方法,因此努力避免深拷贝?
-这是最好的方法吗?还是您可以使用使它更加“优雅”的语言结构(例如using
或某种特别的方法分配)?
谢谢!
编辑:为什么要这样做:当您现有的类来自旧版本的库,并且您要使用依赖的代码来使用该库的较新版本中的内容时。在ObjC中,我定期进行此类扩展以向NSWindow或NSString添加便捷方法,因此我可以像调用SDK一样方便地调用它们,而不必强制转换为专用的子类或调用采用该类的全局函数实例作为参数。
Edit2:这是另一个示例,这次公开与Qt相关。它为QQuickItem::size()
的Qt版本添加了一个替代选择:
template <class QtType>
class Q510QI : public QtType
{
public:
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
QSizeF size()
{
return QSizeF(QtType::width(), QtType::height());
}
#endif
};
#define Q510QIPCAST(instanceptr) static_cast<Q510QI<std::decay<decltype(*instanceptr)>::type>* >(instanceptr)
这使我可以用foo->size()
替换Q510QIPCAST(foo)->size()
(foo指向QQuickItem或继承它)。
很明显,我可以使用一个免费的模板函数(不需要decltype和std :: decay)来做到这一点,但是该函数需要对新的Qt版本有一个明确的实现(调用实际的QQuickItem :: size () 方法)。如果我想添加一系列其他平凡的方法,我会添加尽可能多的#if/#else/#endif
,而在这里我可以只在单个#if/#endif
之间添加那些平凡的函数。
答案 0 :(得分:1)
C ++不像其他语言(如C#)建议的那样提供extension methods。
C ++的方式是添加自由函数或使用继承。
Uniform function call syntax建议可以允许使用您期望的语法(使用自由函数的方式)。