I'm making a small game in the console and have come across a small problem. Let's say I have a class named Canvas
:
canvas.h
class Canvas final {
public:
// Constructor
Canvas(unsigned width = 10, unsigned height = 30);
unsigned outerWidth, outerHeight;
}
canvas.cpp
#include "canvas.h"
Canvas::Canvas(unsigned width, unsigned height) {
outerWidth = width;
outerHeight = height;
// I draw a box (canvas)'s border here
}
Now in the main.cpp
file I declare an instance of the class:
#include "canvas.h"
// The program starts here
int main() {
Canvas myCanvas;
return 0;
}
First of all, I would like to only have 1 member of the Canvas
class, because that's how my program is designed to be. However, when I make an instance of that class, it gets a name (myCanvas
in this example). Then if I want another class (let's say, Entity
) that uses the canvas, I have to say myCanvas.outerWidth
, which is dependent on the object's name. Also, I don't think the myCanvas
variable would be available in the scope of such class anyway.
On the other hand, when I use namespaces, I lose some benefits of using classes (encapsulation (private properties), constructors). So what do I do? Make a static class or namespace or what? I've heard that there isn't a thing called a static class in C++; there are only static properties or methods. I guess putting the static
keyword everywhere isn't good practice. Or is it?
If you want to have a single instance (i guess you want a single instance, not a single member, as a member is one of the component fields of the class, and as such, your class has two member fields now) you are probably talking about the singleton pattern (a class with only one instance and no means to instantiate another).
Just declare the constructor private
or protected
, so client code cannot make a second instance of that object. In that case, you can only use instances already generated for client code, and client code cannot get a new instance (by means of new
operator or declaring an instance in main()
as you do).
class Canvas final {
// Constructor now is private
Canvas(unsigned width = 10, unsigned height = 30);
public:
unsigned outerWidth, outerHeight;
}
I'd recommend you also to declare outerWidth
and outerHeight
as const
if they are to be exposed publicly by the class, so you cannot modify them (making the instance immutable) or declare accessor methods to access those fields and declare a public
and static
field instance
(or theCanvas
), as in:
class Canvas final {
// Constructor
Canvas(unsigned width = 10, unsigned height = 30);
public:
unsigned outerWidth, outerHeight;
static Canvas instance; // we have a static instance defined elsewhere
}
you can instantiate it in a .cc
file with:
#include <canvas.h>
...
Canvas Canvas::instance; // by default 10 by 10, this is the public available instance declared above.
...
in this way, you can use Canvas::instance
everywhere, that will be an instance of your Canvas
class. It will be visible from any source that includes the "canvas.h"
include file, and not only in your main()
routine, as it is in the sample snippet you post.
By the way, there's no much sense in declaring a constructor with parameters if you are only using it once and in your private code. Also no need to declare default parameter values, but you are in your way. You decide.
As it is not fully clear what you are attempting, I could have misunderstood your intentions, so please, don't blame me if this is not what you want, and edit your question to make your target clearer. You have declared outerWidth
and outerHeight
as non-const
and so, they are modifiable by any code that has access to them. It's not clear if you want your instance immutable (not modifiable once it has been instantiated) nor if they have to take their values from some external code.