是否有像C#中的C++扩展?
例如在C#中你可以这样做:
public static uint SwapEndian(this uint value)
{
var tmp = BitConverter.GetBytes(value);
Array.Reverse(tmp);
return BitConverter.ToUInt32(tmp, 0);
}
someuint.SwapEndian();
Run Code Online (Sandbox Code Playgroud)
在C++中有类似的东西吗?
扩展方法(以及"静态类")只存在于C#/ Java语言中,因为设计者认为(Java方式)OOP是The One True Way,并且所有内容都必须是来自类的方法:
这不是C++的做事方式.在C++中,您有名称空间,自由函数和Koenig查找来扩展类的行为:
namespace foo
{
struct bar { ... };
void act_on_bar(const bar& b) { ... };
}
...
foo::bar b;
act_on_bar(b); // No need to qualify because of Koenig lookup
Run Code Online (Sandbox Code Playgroud)
我通常认为扩展方法有害.如果你对一个类附加太多的行为,你可能无法捕获该类存在的原因.另外(如"部分类"),它们倾向于使代码与非本地类相关.这很糟糕.
至于你的问题,在C++中你只需:
template <typename T>
T swap_endian(T x)
{
union { T value; char bytes[sizeof(T)]; } u;
u.value = x;
for (size_t i = 0; i < sizeof(T)/2; i++)
swap(u.bytes[i], u.bytes[sizeof(T) - i - 1]);
return u.value;
}
Run Code Online (Sandbox Code Playgroud)
用法:
swap_endian<std::uint32_t>(42);
Run Code Online (Sandbox Code Playgroud)
或者,如果可以推断出类型:
std::uint64_t x = 42;
std::uint64_t y = swap_endian(x);
Run Code Online (Sandbox Code Playgroud)
C++中没有扩展函数.您可以将它们定义为自由函数.
uint SwapEndian(uint value){ ... }
Run Code Online (Sandbox Code Playgroud)
我发现的一种方法是将重载的“>>”运算符与 lambda 表达式一起使用。下面的代码演示了这一点。你必须知道使用运算符“>>”而不是“->”,这是因为我使用的编译器不允许重载运算符“->”。另外,由于运算符“>>”的优先级低于“->”,因此您必须使用括号强制编译器以正确的顺序计算方程。
最终,它变成了您尝试生成的代码的风格、可维护性、可靠性和简洁性的问题。有人会认为用两个参数定义“SubtractValue”方法会创建更高效的代码,但其他人会认为重载方法更易于维护。最后,由建筑师和开发人员来决定什么对他们的项目来说是重要的。我只是提供一个可能的解决方案。
#include <functional>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
// Some plain demo class that cannot be changed.
class DemoClass
{
public:
int GetValue() { return _value; }
int SetValue(int ivalue) { _value = ivalue; return _value; }
DemoClass *AddValue(int iadd) { this->_value += iadd; return this; }
private:
int _value = 0;
};
// Define Lambda expression type that takes and returns a reference to the object.
typedef std::function<DemoClass *(DemoClass *obj)> DemoClassExtension;
// Overload the ">>" operator because we cannot overload "->" to execute the extension.
DemoClass* operator>>(DemoClass *pobj, DemoClassExtension &method)
{
return method(pobj);
}
// Typical extensions.
// Subtract value "isub".
DemoClassExtension SubtractValue(int isub)
{
return [=](DemoClass *pobj) {
pobj->AddValue(-isub);
return pobj;
};
}
// Multiply value "imult".
DemoClassExtension MultiplyValue(int imult)
{
return [=](DemoClass *pobj) {
pobj->SetValue(pobj->GetValue() * imult);
return pobj;
};
}
int _tmain(int argc, _TCHAR* argv[])
{
DemoClass *pDemoObject = new DemoClass();
int value = (pDemoObject->AddValue(14) >> SubtractValue(4) >> MultiplyValue(2))->GetValue();
std::cout << "Value is " << value;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码输出是“Value is 20”。