-1

I find myself in a situation with the following implementation.

I have a class that is exposed to users.

My intention is to expose a high-level abstraction to the user rather than internal details of my library (or details they would need to handle without this library).

An user can call some method named do_this_for_me and expects something to happen for a service. But internally, my Adapter class needs to maintain some context for this user in a vector called hidden_from_user.

Now I want to consume this vector from my internal implementation of the core library. But I can not because the hidden_from_user private in the Adapter class.

#include <iostream>
#include <vector>

namespace adapter {

    class Adapter {
        public:
            void do_this_for_me(int flags) {
                if(flags == 1) { // just as an example
                    int something_internal = 10;
                    hidden_from_user.push_back(something_internal);
                }
            }
        private:
            // hidden_from_user vector is required store some changes
            // so that my internal implementation can use this vector
            std::vector<int> hidden_from_user;
    };
}


namespace core {
    class InternalThing {
        public:
            int internal_handling(UserApi* handle) {
                // how to access hidden_from_user vector here using handle ?

            }
    };
}




int main() {

}

Please suggest some design options which are considered best practices.

Thanks!

2
  • 2
    How does UserApi relate to Adapter? Do they belong to the same class hierarchy, or are they unrelated classes? Jun 20 at 18:07
  • The pImpl pattern allows a really basic UI class that holds a pointer to an opaque class that holds all the logic. The user can't see anything in the opaque class so they only have access to the UI you give them. Jun 20 at 21:38
2

If it’s C++, you can declare another class or just a method in another class as a “friend”. Which means your data is not really private anymore because the friend can access it. You should only do that if two classes are so closely related that you would never expect to change one but not the other.

1
  • Yes, I will try this friend option
    – Debashish
    Jun 22 at 12:57
0

I think what you're looking for is "Pointer to implementation". Here is a link to an explanation by cppreference https://en.cppreference.com/w/cpp/language/pimpl

As the site states in an example:

// widget.h (interface)
class widget {
    // public members
private:
    struct impl;  // forward declaration of the implementation class
    // One implementation example: see below for other design options and trade-offs
    std::experimental::propagate_const< // const-forwarding pointer wrapper
        std::unique_ptr<                // unique-ownership opaque pointer
            impl>> pImpl;               // to the forward-declared implementation class
};
 
// widget.cpp (implementation)
struct widget::impl {
   // implementation details
};

You declare the interface of your class in the header file (as usual) and point to the type that will contain the information you want to hide (in this case widget::impl). The dummy declaration in the header is needed, so the compiler knows, that some type names widget::impl will be defined somewhere else. In your cpp implementation file, you add the data that should be hidden. As the (in this case) struct is defined in the cpp file, its fields won't be visible, or even accessible, to consumers of your library. However, you can just use all fields of the implementation of the struct in your implementation file, as if it were defined in the header. When you compile you library, the linker will know how to put everything together and you can provide the headers as well as compiled binary to your customers/users.

But be careful! Using pimpl will make your library potentially harder to use, as changes to the internal implementation may break your library's ABI.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.