#Proxy Class
94 messages · Page 1 of 1 (latest)
Its similar to the Adapter design pattern. The name really already explains most of it. It is a proxy class that handles access to another object/class and is usually used if there needs to be simplified interface that the proxy can offer or if the underlying resource requires a lot of tracking/manual handling etc. so that way the proxy class can take care of all the nasty stuff, check if it is used correctly and forward function calls etc. to the underlying class while offering a nicer to use interface.
and how should it be implemented? do you have an example?
is this for school or something?
Yes, I would like to implement a proxy class
ask your teacher what they mean by proxy class
Yes, but I also prefer to learn on my own. There are many students who ask the teacher questions. Sometimes, he doesn't have much time to answer my questions. That's why I'm calling on you 🙂
Moreover, it’s a subject we haven’t seen in class. They want us to learn it by informing ourselves.
A proxy class is a very loose term, it doesn't have a strict definition or strict implementation, it would depend on the context
I just want a small example to know how to implement it in my program
@finite gull has reached level 2. GG!
to solve what?
Solve a problem of data storage in a memory
can you give more information?
An example or explanatory links if you have any. That would help me a lot.
I would like to put 2-byte values ​​into memory with an operator overload. The problem is that the function must return a modifiable variable, therefore an n-bit reference. One of the only solutions found is to create a proxy class.
I'd probably define a proxy class as a class that has the same interface as an other class but that wraps another class to provide a different access or behaviour
what operator overload?
An operator overload by indexing (since I created an array allocated with new and delete).
Yes, I have to mention that the value is uint16 and the memory is a uint8. So, I split the bits into 2 and then made a masking
so what's the issue?
I need to overload the [] operator to be able to do mem[100] = 1234; and have it properly store 2 bytes in little-endian format in a uint8_t array.
The problem is that I need to return a modifiable reference (uint16_t&), but since the data is in two separate bytes, I don't see how to do it properly.
what's the type of mem?
Uint8_t
Why ?
What operator overload if it does not use [] ?
what's the type of mem
mem is a pointer to the array of uint8
alright
so std::uint8_t*
now that makes sense
you could just return (std::uint16_t&)mem[index]
Yes, but the variable will not be modifiable?
why not?
but after that I will get an error: the initial value of a non-constant reference must be an lvalue?
Operator overloading should allow reading and writing the byte in the array. This is the reason why it does not work.
My classmates advised me to use proxy, as it was much easier
show me the code, what I sent should work
The problem is that I don't have the right to share it in a public channel, sorry. 😅
@finite gull has reached level 3. GG!
it'd be like
std::uint16_t& operator[] (std::size_t index)
{
return (std::uint16_t&)mem[index];
}
Yes, that's it, but in the function we have to read and write the 2-byte value in the array. Then we add functions like push and pop.
so what's the problem with this funciton?
I need to overload the [] operator so that I can do something like mem[100] = 1234;, and have it correctly store 2 bytes in little-endian format in a uint8_t array.
The issue is that I need to return a modifiable reference (uint16_t&), but since the data spans two separate bytes, I’m not sure how to do it cleanly.
the code I sent above does that
This function must have both read and write together.
How do you convert the value to uint16&?
Yes but I don't know how to use it
you use it like this
and so if I want to push and pop 2 functions based on operator overloading, will it work?
Its more of an Architecutural / Desing Pattern. It is not concerned with implementation too much. But I could give you an example, sure: c++ class SMTPClient { public: SMTPClient(std::string user, std::string password, std::string server); void sendEmail(std::string title, std::string message, std::string recipient); private: LowLevelSSLSocket soc; }; this would a spin for a more complex "Proxy-Class" but in the end it only functions as a proxy to the low level socket or another networking library. This probably isn't the cleanest example though.
what do you mean push and pop functions?
this could then also make use of RAII and use the destructor to close the socket again for example. As I understand the design pattern it is really just a "wrapper" around a resource that would otherwise be hard to handle
but I will make sure to read up on it myself later again and possibly correct myself ^^
Thank you
sure?
Ok
I have one last quick question: when reading and writing uint16_t values in a uint8_t array, is the usual method to mask, increment by 1, and then combine the bytes?
i found this video: https://youtu.be/nKYUdgLfCO0 (didn't watch yet)
In this video we will learn about a Proxy Design Pattern In C++.
Few points about the proxy design patterns are:
- A proxy class acts as a surrogate or placeholder for another object and controls access to it.
- The primary purpose of a proxy class is to provide a level of indirection, allowing you to control access to the underlying object by ...
not really, it's common to just reinterpret_cast or bit_cast/memcpy
sorry I didn't get that question.
When reading and writing uint16_t values into a uint8_t array, is the usual method to use bitwise operations like masking with &, combining with |, and incrementing the index by 1 to access the second byte?
you can do it with bitshift and OR but in this case you don't need to
ah I see. This should rarely happen. For me this would indicate some design mismatch between 2 systems. One that requires uint16_t values and one that requires uint8_t values ... you can split the values using bit shifts into 2 values for sure. But to me this would indicate some logic flaw somewhere else.
it's because they are representing some memory, they are likely doing a toy VM or something like that
but I guess just reinterpret_cast ing it would be the preferred solution
or using a union
So my solution would not be ideal ? for example : If my 16-bit variable is foo, then foo & 0xff gives me the lower 8 bits, and (foo & 0xff00) >> 8 gives me the upper 8 bits. To combine them again, I would use foo = foolow | (foohigh << 8)
that's fine too
that might be, but very convenient to use. And since it doesn't have a type index it should in theory always work even if it is technically UB
the only reason it works is because compilers agreed to let it work
So if I implement this in 2 operator functions: 1 read and the other write, is that correct?
@finite gull has reached level 4. GG!
that's fine but then you can't return a reference
sure. Yeah, you probably shouldn't use it. It's just my lazy thinking ^^
yes, but if I use your suggestion will it be correct? (std::uint16&)
But same applies to many other things we use daily like #pragma once it's never been in the standard, but still works on all major compilers
in theory a compiler could just ignore it
@fossil halo has reached level 4. GG!
Would it be possible if I send my code privately?
sure