user42140
user42140

Reputation: 257

Write a proxy class in C++

I have a C++ wrapper class which encapsulates some hardware extraction as:

class DeviceWrapper
{
private:
    PhysicalDevice mDevice;
};

There are various classes that access the device and most of them accept the underlying device as their first parameter, like so:

void someFunc(PhysicalDevice & device);

So I currently have the following getter method in my wrapper class:

PhysicalDevice & DeviceWrapper::getPhysicalDevice()
{
    return mDevice;
}

And I use it like this: someFunc(myWrapper.getPhysicalDevice());

However, this looks a bit cumbersome. Is there a way to define some sort of operator which returns the reference to this device and then I can basically use the reference to the wrapper class wherever the reference to the PhyscialDevice is needed.

Upvotes: 1

Views: 1103

Answers (3)

Daniel Trugman
Daniel Trugman

Reputation: 8501

If you have full control over the API, I would advise against the cast operator and would suggest blocking any kind of access to the underlying device object.

Why? Because APIs should be easy to use but hard to misuse. If you allow users to access the underlying object both directly and through the proxy, it might result in inconsistent run-time states.

Instead rather wrap all the API methods using your proxy, thus managing the state and keeping it consistent:

class DeviceWrapper
{
public:
    void someFunc1(PhysicalDevice & device) { ::someFunc1(mDevice); }
    void someFunc2(PhysicalDevice & device) { ::someFunc2(mDevice); }

private:
    PhysicalDevice mDevice;
};

Upvotes: 2

Richard Hodges
Richard Hodges

Reputation: 69864

There are 2 common ways of expressing this:

  1. provide an implicit conversion:

 

class DeviceWrapper
{
    operator PhysicalDevice&() { return mDevice; }
private:
    PhysicalDevice mDevice;
};

 

  1. re-implement the function as a method (for reasons mentioned in another answer, I would favour this approach):

 

class DeviceWrapper
{
    auto someFunc() { return ::somefunc(mDevice); }

private:
    PhysicalDevice mDevice;
};

Upvotes: 3

Quentin
Quentin

Reputation: 63124

Yes, exactly!

class DeviceWrapper
{
    // ...
public:
    operator PhysicalDevice &() {
        return mDevice;
    }
};

And you're done: a DeviceWrapper can now be converted implicitly to a reference to its PhysicalDevice, for example in function calls expecting a PhysicalDevice &.

Upvotes: 2

Related Questions