Good OOP practice?
-
I'm trying to write a small and simple GUI library in C++. Kind of like CDialog in MFC and all.. The problem is, I learnt C, and I've always had problems getting into the C++ part. I know the syntax and all, but it's rather the concept I can't always grasp. Now this may seem trivial, but it matters to me. My problem is this: Let's say I want to encapsulate a Window class into its own class, and also a normal overlapped window. Now my reasoning would be something like this: A window is based on a window class, so to make a window we'll need to pass our window object a windowclass object when we create it. Now I have several questions. First of all, look at two different approaches to implement the WindowClass class:
// Implementation nr.1
// _wcex is a member variable of WindowClass of type WNDCLASSEX
WindowClass::WindowClass(HINSTANCE hInstance)
{
// Fill in all parts of _wcex structure with default values
if(!RegisterClassEx(&_wcex))
// throw exception
}As u can see we call api function RegisterClassEx() to register the class in the constructor, so this class would only have a constructor and a destructor, and perhaps some additional constructors to allow more parameters to be passed to the WNDCLASSEX structure for greater customisation. Great idea, u just pick the constructor u need and ur window class is registered just by creating the object. Now the other approach:
// Implementation nr.2
WindowClass::WindowClass(HINSTANCE hInstance)
{
// Fill in _wcex fields
_wcex.hInstance = hInstance; // ...
}void WindowClass::Register()
{
if(!RegisterClassEx(&_wcex))
// throw exception
}In this implementation the only difference is we put the actual api call in a seperate method, so we can add Set() methods to the class for any field of the WNDCLASSEX structure, so we can customize the entire class. The only downside is it will result in more method calls depending on how much we want to customize. Now I realize this probably doesn't make much difference in practice, it both works, but I was wondering what you feel is the right way to do it. Personally I feel the right thing to do is to actually avoid API calls in constructors/destructors. I suppose it's more of a OO philosophical question though. If you could share your opinions on it, or direct me to some articles about this I'd be very grateful. I have another problem, but seeings this post is already kind of longwinded, I think i'll hold it back until i've ha
-
I'm trying to write a small and simple GUI library in C++. Kind of like CDialog in MFC and all.. The problem is, I learnt C, and I've always had problems getting into the C++ part. I know the syntax and all, but it's rather the concept I can't always grasp. Now this may seem trivial, but it matters to me. My problem is this: Let's say I want to encapsulate a Window class into its own class, and also a normal overlapped window. Now my reasoning would be something like this: A window is based on a window class, so to make a window we'll need to pass our window object a windowclass object when we create it. Now I have several questions. First of all, look at two different approaches to implement the WindowClass class:
// Implementation nr.1
// _wcex is a member variable of WindowClass of type WNDCLASSEX
WindowClass::WindowClass(HINSTANCE hInstance)
{
// Fill in all parts of _wcex structure with default values
if(!RegisterClassEx(&_wcex))
// throw exception
}As u can see we call api function RegisterClassEx() to register the class in the constructor, so this class would only have a constructor and a destructor, and perhaps some additional constructors to allow more parameters to be passed to the WNDCLASSEX structure for greater customisation. Great idea, u just pick the constructor u need and ur window class is registered just by creating the object. Now the other approach:
// Implementation nr.2
WindowClass::WindowClass(HINSTANCE hInstance)
{
// Fill in _wcex fields
_wcex.hInstance = hInstance; // ...
}void WindowClass::Register()
{
if(!RegisterClassEx(&_wcex))
// throw exception
}In this implementation the only difference is we put the actual api call in a seperate method, so we can add Set() methods to the class for any field of the WNDCLASSEX structure, so we can customize the entire class. The only downside is it will result in more method calls depending on how much we want to customize. Now I realize this probably doesn't make much difference in practice, it both works, but I was wondering what you feel is the right way to do it. Personally I feel the right thing to do is to actually avoid API calls in constructors/destructors. I suppose it's more of a OO philosophical question though. If you could share your opinions on it, or direct me to some articles about this I'd be very grateful. I have another problem, but seeings this post is already kind of longwinded, I think i'll hold it back until i've ha
What you want to do is to encapsulate all low level API details, so that your library can be used anywhere. Right? Well, if that's the case, you should not create a light wrapper. What you are doing is coupling the API calls in one object. What you want to be doing is define a set of styles for the window. Define all the other stuff yourself also (windows messages, controls, etc..) and in your code, translate this stuff into windows API calls. This way, you can provide different implementations (makes your project portable). In the ideal case, you don't have to modify your application when you compile it under Linux or whatever GUI. The only thing that has to be done is to use a different implementation of your library! To get back on track here and to answer your question: I think that you should go for the two stage window construction. One rule is to never throw an exception from a constructor. So here you have almost no way of notifying the caller of your code that creation failed. One other suggestion though. For abstraction purposes, you should hide implementation details. The win API is an implementation detail. So hInstance variables should be hidden. The raw styles should be hidden. Try to hide as much handles as you can, etc, etc.. Behind every great black man... ... is the police. - Conspiracy brother Blog[^]