C++函数类,它为某些函数增加额外的处理

C++函数类,它为某些函数增加额外的处理,c++,c++11,c++14,generic-programming,C++,C++11,C++14,Generic Programming,我试图为遗留继承层次结构创建一个包装类,它不是严格多态的。在包装类中,我为一些方法添加了额外的功能,但对于许多其他方法,我只想调用包装类方法。 我想知道是否有一种方法可以在wrapper类中编写一个通用的wrapper函数,这样我就可以像没有wrapper类一样以正常的方式调用wrapped函数。 可能我错了,但我认为重载运算符->不起作用,因为包装类中有一些方法,我想在调用包装类函数之前对这些方法进行一些处理,但对于其他许多方法,我不需要这样做。 我还查看了Herb Sutter的包装模式,同

我试图为遗留继承层次结构创建一个包装类,它不是严格多态的。在包装类中,我为一些方法添加了额外的功能,但对于许多其他方法,我只想调用包装类方法。

我想知道是否有一种方法可以在wrapper类中编写一个通用的wrapper函数,这样我就可以像没有wrapper类一样以正常的方式调用wrapped函数。

可能我错了,但我认为重载运算符->不起作用,因为包装类中有一些方法,我想在调用包装类函数之前对这些方法进行一些处理,但对于其他许多方法,我不需要这样做。

我还查看了Herb Sutter的包装模式,同样,我可能错了,但这需要我有一个lambda来访问包装函数。

我想知道是否有人知道这是否可以实现

我已经把代码放在@ 在这里而不是

wrapper->operator()([](Derived& x)
{
   x.print();
});

有什么办法可以让我

wrapper->print();

提前感谢您的回答。

并没有给出您想要的结果,但在编写必需的代码方面仍然相对便宜:继承:

class Wrapped
{
public:
    void f();
    void g();
};

class Wrapper : private Wrapped
{
public:
    // replacing Wrapped's f with own variant:
    void f() { pre(); Wrapped::f(); post(); };
    // pulling Wrapped's g into public  domain again:
    using Wrapped::g;
};
因此,您所要做的就是使用声明添加相应的语句。如果你现在问:为什么不公开继承,那么我就不必继承?
Wrapped* w = new Wrapper();
w->f(); //Wrapped's version of f will be called, as f in given example is not virtual!

也许你说我永远不会直接用包装纸。。这是可行的,但是仍然在某处使用它,然后得到bug的危险仍然存在于公共继承中……

您的问题是您实际上使用了指针

目前,

wrapper->operator->()->print();
你可以写信

(*wrapper)->print();
如果替换不需要的指针

wrap<Derived> *wrapper = new wrap<Derived>(der);

同样地

wrapper->operator()([](Derived& x)
    {
       x.print();
    });
将成为

wrapper(([](Derived& x)
    {
       x.print();
    });

但那需要我有一个lambda-你永远不需要lambda。lambda只是经典函数对象的语法糖。你可以编写经典的C++98代码,让你获得与lambda相同的效果,只是更详细。你应该在问题中以文本形式提供代码,而不是通过外部链接!请看一看讨论,也许你可以更准确地描述一下你真正想要实现的目标?@Aconcagua-当然,下一次将在问题中发布代码。。是的,正如@Jarod42所说,我的问题是指针的使用。。一旦我做了他建议的更改,我现在就可以调用包装类的函数,而无需显式使用操作符->。Thanks@Joseph您在包装器类中添加了新函数吗?然后考虑贾罗德的GET方法,选择一个或另一个打印变量只在对象上使用的操作符是危险的:包装器->打印得到原始打印vs.它在*wrapper->print和*wrapper->print的指针上变得更加明显,但我仍然不能推荐它……如果不替换的话:*wrapper->print应该也能工作,不是吗?@Aconcagua:是的,添加了。不过,我们总是使用t的打印功能。如果包装纸需要更换印刷品怎么办?我们可以同时调用wrapper.print changed和wrapper->print unchanged?我不想进一步评论这个。。。旁注:任何->打印变体都不使用包装器的运算符。@Aconcagua:如OP所写,包装器->f。。调用常规派生函数,而wrapper.f。。将为每个函数添加专用内容:包装器重新定义prettyPrint,但不定义print和调用派生函数。如果它是泛型的,我会用wrapper->f来表示额外的内容,用wrapper.get.f来表示常规调用..f和.get.f来表示实际调用的内容,而不是使用这两种方法。或->仅限。我理解这个问题,因此它应该是透明的,始终使用.f或->f,使用已更改的变体(如果存在),或者使用原来的变体。通常简单地通过继承来解决,但不是严格的多态性。我得出结论,有一些非虚函数也应该改变?假设OP应该为问题添加一些细节。。。
wrapper->operator->()->print();
wrapper->print();
// or wrapper.operator->()->print(); :)
wrapper->operator()([](Derived& x)
    {
       x.print();
    });
wrapper(([](Derived& x)
    {
       x.print();
    });