C++ 如何在包装现有类时使变量的返回有效
我正在包装一个现有的库,而不会引入太多的开销,这样包装库就可以像现有库一样快速运行。我这样做是为了使接口(语法)与我的旧代码兼容 比如说,现有的类称为BASE,它是模板类。我把它包装如下C++ 如何在包装现有类时使变量的返回有效,c++,performance,wrapper,C++,Performance,Wrapper,我正在包装一个现有的库,而不会引入太多的开销,这样包装库就可以像现有库一样快速运行。我这样做是为了使接口(语法)与我的旧代码兼容 比如说,现有的类称为BASE,它是模板类。我把它包装如下 template<class T> class Wrapper{ public: Wrapper() : base(){}; /* ... */ Wrapper<T>
template<class T>
class Wrapper{
public:
Wrapper() : base(){};
/* ... */
Wrapper<T> dosomething ( const Wrapper<T>& a )
{
Wrapper<T> output;
output.base = CallExistingClass(a.base);
return output;
}
private:
BASE<T> base;
};
模板
类包装器{
公众:
包装器():base(){};
/* ... */
包装物剂量测定(常量包装物和a)
{
包装输出;
output.base=CallExistingClass(a.base);
返回输出;
}
私人:
基地;
};
对于任何没有返回类型的成员函数,使用这个或*可以生成非常高效的代码。但是,当返回类型为
Wrapper<T>
包装器
是必需的,调用包装库的速度总是慢5-10倍。因为它只是一个包装类,所以我所需要的所有操作就是提取成员变量“base”(例如“a.base”),使用现有类中的函数对a.base进行处理,然后将结果传输到“output.base”并返回“output”
我必须确保包装器类与我的旧代码的旧语法匹配,这里不能选择按指针返回。我能想到的解决方法是使用静态变量通过引用返回
Wrapper<T>& dosomething ( const Wrapper<T>& a)
{
static Wrapper<T> output;
output.base = CallExistingClass(a.base);
return output;
}
Wrapper&dosomething(常量Wrapper&a)
{
静态包装输出;
output.base=CallExistingClass(a.base);
返回输出;
}
我想知道是否有更快的方法来做到这一点,而不产生额外费用/临时费用?期待任何有用的评论。一个简单的优化是使用初始化而不是赋值,例如
template <class... U>
Wrapper(U&&... args) : base(std::forward<U>(args)...) {} // forward constructor
Wrapper<T> dosomething ( const Wrapper<T>& a )
{
Wrapper<T> output{CallExistingClass(a.base)};
return output;
}
然后您可以以Wrapper::dosomething(a)
的形式使用它,而无需创建额外的对象
(2) 此外,您还可以使用数据成员而不是参数,例如
Wrapper<T> dosomething const ()
{
Wrapper<T> output{CallExistingClass(base)};
return output;
}
Wrapper dosomething const()
{
包装器输出{CallExistingClass(base)};
返回输出;
}
并以
a.dosomeghing()
的形式调用它。一个简单的优化是使用初始化而不是赋值,例如
template <class... U>
Wrapper(U&&... args) : base(std::forward<U>(args)...) {} // forward constructor
Wrapper<T> dosomething ( const Wrapper<T>& a )
{
Wrapper<T> output{CallExistingClass(a.base)};
return output;
}
然后您可以以Wrapper::dosomething(a)
的形式使用它,而无需创建额外的对象
(2) 此外,您还可以使用数据成员而不是参数,例如
Wrapper<T> dosomething const ()
{
Wrapper<T> output{CallExistingClass(base)};
return output;
}
Wrapper dosomething const()
{
包装器输出{CallExistingClass(base)};
返回输出;
}
并以
a.dosomeghing()
的形式将其称为一个小小的改进。函数中的static使其在类方面是静态的。作为成员添加输出
,将使其线程更安全。这是一个非常好的观点,谢谢先生。我真的很期待通过直接窃取结果的内存来摆脱临时变量“output”。但我不知道此时如何将move构造函数添加到基类和包装类中。这也会有帮助。看看这个答案:添加“输出”作为成员会使它更线程安全,有可能显示一些代码来实现这一点吗?AFAIK,只能将指向“output”的指针添加为成员,否则,编译器错误为“类型不完整”。关于move构造函数,我已经合并了这些构造函数,但只有在计算量较大时才与直接调用基类的效率相匹配。另外,您可以为移动构造函数显示一些代码来验证我是否正确。使用static
和通过引用返回会导致对dosomething
的不同调用返回相同的对象。这是你的意图吗?此外,为什么不将dosomething
声明为返回类型dosomething()const
,并使用成员base
而不是a
?如果您喜欢将a
声明为参数,我认为最好将dosomething
声明为静态成员函数,因为它不使用私有数据成员。这只是一个小小的改进。函数中的static使其在类方面是静态的。作为成员添加输出
,将使其线程更安全。这是一个非常好的观点,谢谢先生。我真的很期待通过直接窃取结果的内存来摆脱临时变量“output”。但我不知道此时如何将move构造函数添加到基类和包装类中。这也会有帮助。看看这个答案:添加“输出”作为成员会使它更线程安全,有可能显示一些代码来实现这一点吗?AFAIK,只能将指向“output”的指针添加为成员,否则,编译器错误为“类型不完整”。关于move构造函数,我已经合并了这些构造函数,但只有在计算量较大时才与直接调用基类的效率相匹配。另外,您可以为移动构造函数显示一些代码来验证我是否正确。使用static
和通过引用返回会导致对dosomething
的不同调用返回相同的对象。这是你的意图吗?此外,为什么不将dosomething
声明为返回类型dosomething()const
,并使用成员base
而不是a
?如果您喜欢将a
声明为参数,我认为最好将dosomething
声明为静态成员函数,因为它不使用私有数据成员。