1

I am making a C++ glfw wrapper for myself to use. I want to have classes like Monitor, Window, Context that would be wrappers for glfw objects like GLFWMonitor* or GLFWWindow*. The problem is that if I want to have a method create_window() in the Window class, it must have access to the underlying raw glfw pointer in Monitor class. At the same time, if I wanted the Monitor class to have a method like enumerate_windows(), it would need access to the underlying glfw window pointer. I could have a public method get_raw_handle() in both classes, but implementation details are supposed to be hidden and I don't want the user to be able to access this information. It should only be available to the library.

I thought that I could friend the classes to each other, but that doesn't seem right, as if I wanted to add a new class, I would have to friend all existing classes to it and the other way around. It would also require forward declarations for everything and right now my library is header only.

I also thought that maybe all these objects could inherit from some kind of super WindowingSystemObject class that would have a protected method get_raw_handle(), but that would mean that the handle would need to be universal (like a void*) and then cast to the appropriate type.

All this seems so complicated. Instead of writing code I feel like some kind of a philosopher. I don't know anymore if I should make it in C++ (with classes) or just make it in C and don't care about any encapsulation as long as it works.

  • You might make a class GetGLFWMonitor, and make it a friend to any wrapper class that holds GLFWMonitor instances. Then, all methods in GetGLFWMonitor class are protected, and available to a list of friend classes of your other wrappers that need that. This will localize the knowledge and friending going on. – BobDalgleish Mar 6 at 22:34
  • C++ does not have the concept or feature of "library internal visibility" (unlike the package visibility in Java or the internal keyword in C#). In fact, in C++ you also do not have the option to selectively export C++ definitions. Which means all C++ definitions are available to downstream C++ consumers of your library, which means there is no true internal visibility whatsoever. – rwong Mar 7 at 8:23
1

The problem is that if I want to have a method create_window() in the Window class, it must have access to the underlying raw glfw pointer in Monitor class.

This is not actually a problem. You're thinking about each object as though it were some kind of isolated, locked-off thing which has no relationships to anything else.

Yet the API you're trying to wrap says otherwise.

The act of creating a GLFW window can utilize a monitor. As such, the two objects are naturally related. So it makes perfect sense for the two objects to talk to each other in ways that the outside world cannot use to talk to them.

At the same time, if I wanted the Monitor class to have a method like enumerate_windows(), it would need access to the underlying glfw window pointer.

Why would you? To my knowledge, GLFW doesn't store a list of GLFWwindows for each GLFWmonitor. So if your Monitor class wants to store a list of windows that can be enumerated, then it should store a list of your Window wrapper, not of GLFWwindow pointers.

I could have a public method get_raw_handle() in both classes, but implementation details are supposed to be hidden and I don't want the user to be able to access this information.

Are you so certain of that? In your first sentence, you said "I am making a C++ glfw wrapper for myself to use." That's a very different project from making an arbitrary abstraction which could be implemented through GLFW or through some other API. The former, by definition, assumes that GLFW exists and is being used.

Also, if your library is going to be header-only, it's really hard to hide the underlying system you're using when its going to be included by everyone who includes your library. It's best to just own what you've created: a GLFW wrapper.

Lastly, by making GLFW part of your library's interface (rather than trying to pretend it doesn't exist), as GLFW changes, users can use the new GLFW APIs before you've updated your library to add wrappers for them.

as if I wanted to add a new class, I would have to friend all existing classes to it and the other way around.

Nonsense. You add relationships to the extent that relationships are needed. Your Window needs to be able to extract the GLFW type from Monitor. But Monitor has no need to do that to Window.

| improve this answer | |

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.