I am trying to learn some C++ coming from C#. One of the things I liked in C# was the extensions like CustomItem.ToString()
and was curious how I could implement something like that in C++. I am using std::vector<unsigned char>
to store a buffer and then processing it byte by byte.
I have the following function:
int DataParser::ToLittleEndianInt(std::vector<unsigned char> ba) //Little Endian
{
long int Int = 0;
int arraySize = ba.size();
if (arraySize ==4)
{
Int = ba[0] | ((int)ba[1] << 8) | ((int)ba[2] << 16) | ((int)ba[3] << 24);
}
else if (arraySize == 2)
{
Int = ba[0] | ((int)ba[1] << 8);
}
else if (arraySize == 1)
{
Int = ba[0];
}
return Int;
}
Here I can send it a vector from one to 4 bytes and it will convert to integer for me. Is there a way for me to use it in a way like this:
std::vector<unsigned char> CurrentBytes(4);
for (int i = 0; i < 4; i++)
CurrentBytes[i]=1;
// how can we do this?
int results = CurrentBytes.ToLittleEndianInt();
//or
int results = CurrentBytes->ToLittleEndianInt();
I just feel it is quite readable and want to have extensions for strings, dates, int, dollars and so on.
UPDATE:
I tried doing the custom class as suggested, but I am getting compile time errors. I put this in my .h file:
class Byte
{
public:
Byte();
~Byte();
std::string DataType;
int ColumnWidth;
std::vector<unsigned char> data;
int ToLEInt() {
long int Int = 0;
int arraySize = this->ColumnWidth;
if (arraySize == 2)
{
Int = this->data[0] | ((int)this->data[1] << 8);
}
else if (arraySize == 1)
{
Int = this->data[0];
}
return Int;
};
};
That throws the error:
Error LNK2019 unresolved external symbol "public: __thiscall Byte::Byte(void)" (??0Byte@@QAE@XZ) referenced in function "public: static void __cdecl DataParser::Parse(class nlohmann::basic_json<class std::map,class std::vector,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool,__int64,unsigned __int64,double,class std::allocator,struct nlohmann::adl_serializer>)" (?ParseToDataTable@Parse@@SAXV?$basic_json@Vmap@std@@Vvector@2@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@_N_J_KNVallocator@2@Uadl_serializer@nlohmann@@@nlohmann@@@Z)
I also tried declaring it as:
const Byte& ToLEInt(const Byte& s)const {}
That was the way I saw done in Stephen Prata's C++ Primer, but then I still get errors, and I would have to use it like this in my cpp:
std::vector<unsigned char> test(3);
for (int i = 0; i < 2; i++)
test[i] = i;
Byte CurrentBytes;
CurrentBytes.data = test;
CurrentBytes.ColumnWidth=2;
int results = CurrentBytes.ToLEInt(CurrentBytes);
//instead of
int results = CurrentBytes.ToLEInt();
I then tried putting the declaration outside of the class block, but then I got an error that LEInt wasn't defined,
int Byte::ToLEInt(){}
When I tried adding int ToLEInt();
to the class block, then it complained that it was already defined.