I'm starting with C++ programming and I believe I have got a grasp about pointers. However I'm trying to understand the best practices for pointers and functions while using struts.
Toy example code
I have made below Toy example code to exemplify two ways to perform same thing:
#include <stdio.h>
struct rectangle {
int width;
int length;
};
void printRect(rectangle rect) {
printf("Rectangle: width=%d, length=%d\n",rect.width, rect.length);
}
void doubleSizeRectangle_1(rectangle *rect) {
rect->width = rect->width*2;
rect->length = rect->length*2;
}
rectangle doubleSizeRectangle_2(rectangle rect) {
rectangle *r = ▭
r->width = r->width*2;
r->length = r->length*2;
return *r;
}
rectangle doubleSizeRectangle_3(rectangle rect) {
rect.width = rect.width*2;
rect.length = rect.length*2;
return rect;
}
int main()
{
rectangle rect;
rect.width = 2;
rect.length = 5;
rectangle *rect_pointer = new rectangle;
rect_pointer = ▭
printRect(rect);
printRect(*rect_pointer);
printf("Applying functions:\n");
doubleSizeRectangle_1(rect_pointer);
printRect(rect);
rect = doubleSizeRectangle_2(*rect_pointer);
printRect(rect);
rect = doubleSizeRectangle_3(*rect_pointer);
printRect(rect);
}
That code returns following output:
Rectangle: width=2, length=5
Rectangle: width=2, length=5
Applying functions:
Rectangle: width=4, length=10
Rectangle: width=8, length=20
Rectangle: width=16, length=40
The first two prints are just to check about pointers usage.
The remaining prints are to check the three functions doubleSizeRectangle_1, doubleSizeRectangle_2 and doubleSizeRectangle_3 that perform same actions in different ways. The first one returns void and uses a pointer as input, whereas the second and third one have a variable as input and return a rectangle struct. Third option seems better than second, but would like to confirm. I'm not sure about the first one compared to the rest.
Question
Which option would be better in terms of best practice and why? Is there any of these options better in terms of avoiding memory leaks? May there be any other ways using pointers, and would those be even better than those I posted?
"best" is rather subjective, but using something complicated when there is no need to is not "best" in any sense.
Don't use new. Don't use pointers when there is no need to. Prefer references over pointers when nullptr is not a valid paramter (it isn't in your case). Use const references to avoid copies:
#include <stdio.h>
struct rectangle {
int width;
int lenght;
};
void printRect(const rectangle& rect) {
printf("Rectangle: width=%d, lenght=%d\n",rect.width, rect.lenght);
}
void doubleSizeRectangle_3(rectangle& rect) {
rect.width = rect.width*2;
rect.lenght = rect.lenght*2;
}
int main()
{
rectangle rect;
rect.width = 2;
rect.lenght = 5;
doubleSizeRectangle_3(rect);
printRect(rect);
}
Your function passed a pointer and returned the modified parameter. You do not need both. I changed it to return nothing and take the paramter by reference, because passing a nullptr does not make sense here.
You should also use a constructor to initialize the structs members, and prefer the type safe C++-IO (std::cout) over the non-typesafe C-IO.
For further reading: Why should C++ programmers minimize use of 'new'?
I suggest you to avoid doing like this:
rectangle doubleSizeRectangle_2(rectangle rect) {
rectangle *r = ▭
r->width = r->width*2;
r->lenght = r->lenght*2;
return *r;
}
you don't need to access that parameter using a pointer inside the method, you could simply access to object, because it's a copy.
As best practice, in order to minimize the risk of memory leak, the suggestion is to use smart pointers like this:
std::unique_ptr<rectangle> smartptrToRectangle(std::make_unique<rectangle>());
a smart pointer is a class that implements the RAII idiom:
RAII explanation
a smart pointer does destroy the element for you as soon as it go out of scope.
I would not use pointers for a function that edits a rectangle struct at all:
void doubleSizeRectangle(rectangle& rect)
{
rect.width = rect.width*2;
rect.lenght = rect.lenght*2;
}
The main difference between passing a pointer and a reference is just that a pointer can be unassigned while a reference always references a rectangle struct.
Your doubleSizeRectangle_1 essentially does the same thing. You should consider checking if the pointer is assigned if you want to stick to using pointers.
doubleSizeRectangle_2 makes no sense. You are passing your struct by value which means your function receives a copy of it. You then create a pointer to this object, manipulate it through that pointer to return it as a value again. The use of the pointer is useless there.
doubleSizeRectangle_3 is just doubleSizeRectangle_2 without the weird pointer. I wouldn't use this, it does at least one copy (when passing to the function) and one move operation (returning the struct from the function) that isn't nessecary for a function that just want's to edit the struct. Stick to my suggestion or your doubleSizeRectangle_1.
Related
I have a class like below
class Circle{
private:
int radius;
Circle* next
}
And I gonna creat set/get method...but i have no idea which data type i have to use.
int Circle::getRadius() const{return radius}
or
int& Circle::getRadius() const{return radius}
void Circle::setRadius(int r)
or
void Circle::setRadius(int& r)
CirCle* Circle::getNext() const{return next}
or
Circle& Circle::getNext() const{return *(next)}
void Circle::setNext(Circle& circle)
{
next = new Circle;
next = circle;
}
or
void Circle::setRadius(Circle circle)
{
next = new Circle;
next = circle;
}
or
void Circle::setRadius(Circle* circle)
{
next = circle;
}
I'm famliar with Java quite a lot. And Java argument are all reference. But cpp is quite different so it drive me crazy. Thanks for your help.
First I'd just recommend going through some C++ tutorials. Your question is probably going to get downvoted here because it looks like you really didn't try to search for a solution to your problem, but rather just ask SO for help.
Need to understand a few things with C++. Learn pass by reference vs pass by value. Are primitives passed by reference or by value?
You also should look at pointers. You're kinda mixing up syntax in there a little bit. * is to de reference a pointer. & is to get the memory address of a certain object.
Explore these concepts and you'll find the answer to your question, and learn more about C++.
Try looking at this site for some info.
http://www.learncpp.com/cpp-tutorial/84-access-functions-and-encapsulation/
If you have any other questions, feel free to let me know. :)
Happy to help.
You should use:
int Circle::getRadius() const{return radius}
Why?
First because you don't want your getter to modify your object (that is done by the const after () ), and you don't want caller to your getter to be able to modify your radius either, in fact:
int& Circle::getRadius() const{return radius}
should not even compile. it would have to be:
const int& Circle::getRadius() const{return radius}
In this case the reference to radius returned is const and therefore, the caller cannot modify the radius via this getter.
Although it's totally correct, when dealing with primitive types in C++ one usually prefer to copy rather than to hold const reference. Why? because copy on primitive costs less than have to dereference it each time you need to use it.
Use:
void Circle::setRadius(int r)
Why?
Like before, using an int, prefere to copy the value to use a reference that you'll have to (implicitly) derefence on use.
In this case:
CirCle* Circle::getNext() const{return next}
or
Circle& Circle::getNext() const{return *(next)}
Why? One thing is sure, you won't be able to use the second one, like in the first case your return value will have to be const Circle&. Plus, you want to be able to return a "invalid" value. In C++ not like in Java, you cannot return an "invalid" reference. So the best thing is to return a pointer which will have "NULL" value if "invalid".
After that, if you want your caller to be able to modify the "next Circle" you'll have to go with a Circle* return. If you don't want your caller to be able to modify the result you'll have to go with a const Circle*
const CirCle* Circle::getNext() const{return next}
or
Circle* Circle::getNext() const{return next}
Some people think it's a bad thing to have a const method that return a non const pointer. For certain reasons, I don't, but both are syntaxly correct.
Use:
void Circle::setNext(Circle* circle)
{
next = circle;
}
Why? For your SetNext, it depends on who will have to manage the memory (ie destruction) used by your "next circle" if it's an external class (I think it's the easiest), like a manager for exemple go with that
For your setRadius, simply use:
void Circle::setRadius(int value)
{
radius = value;
}
[Edit: ] Example of Circle class:
Here what would an external manager (like a Circle list) would look like:
class CircleList //Manager as I told
{
public:
Circle* createCircle(int _radius)
{
Circle* circle = new circle(_radius);
//manage here the add to the list of circle
}
void destroyCircle(Circle* _circle)
{
//Manage here the remove of the list
delete _circle;
}
~CircleList()
{
while( first )
{
destroyCircle(first);
}
}
private:
Circle* first = NULL;
};
class Circle
{
public:
Circle(int _radius) : radius(_radius) { }
void setNext(Circle* _circle)
{
next = _circle;
}
Circle* getNext() const
{
return next;
}
void setRadius(int _value)
{
radius = _value;
}
private:
Circle* next = NULL;
int radius = -1;
};
Here, only CircleList manage the list and memory used by circles. If you want to encapsulate even more, make setNext/getNext private and CircleList a friend of circle (once again some will judge, let them :p)
If you wanted to manage memory inside the Circle class, a circle would exist only if its predecessor exist, and if you delete one Circle you would delete all the ones after in the list(I can't see the application this...). In this case you would have something like:
class Circle
{
public:
Circle(int _radius) : radius(_radius) { }
void setNext(int _radius)
{
next = new Circle(radius);
}
void removeNext()
{
delete next;
next = NULL;
}
Circle* getNext() const
{
return next;
}
void setRadius(int _value)
{
radius = _value;
}
~Circle()
{
delete next;
}
private:
Circle* next = NULL;
int radius = -1;
};
Note that you now have a destructor on circle and that when destroying one circle, it destroys all the circle that follow in the list (only way I see to avoid leak and external "holder" of circles)
Plus if you have a really long list, it may cause problems when destroying as a destructor calls (implicitly) the destructor of its successor, you may end up with a stack overflow.
That's why I was telling you that a manager external to the class was the best solution to me, but maybe some other people have better ideas :)
First of all, in Java all are passed by value!
In case of references, it is passed the value of the reference. Because of that it is misunderstood generally.
In case of C++, you can return/pass by value or reference. In your example, int value would be returned by value simply; supposing that probably you would only need its value.
In case of a complex object, you could use reference or pointer. They are actually -almost- the same. You can find sources to look the differences in detail, but here let me tell simply: Pointers are kept in C++ to be compatible with C; references are considered instead. So, you could try to use references mostly.
You need to know the difference of using values by copy and by reference and using pointers.
Passing values by copy, say:
int radius = 2;
setRadius( radius );
Creates a copy of 2 within the function. Whatever changes you do to that value within the function won't change the variable radius that you created outside.
Pointers hold a value that is the memory address of some variable. No matter the type you're using, a pointer only takes up 4 bytes in memory.
int radius = 2;
int *radiusPtr = &radius; // radiusPtr now points to the address of radius
std::cout << *radiusPtr << std::endl; // > 2
setRadius( radiusPtr ); // Passing a pointer to setRadius
Passing by reference is, in a way, similar to pointers but it's defined as "passing the variable itself". You could use a pointer to change the value of the pointed left value, but you can use a reference to change the values of the original variable. You could even use a reference to a pointer to change the original pointer.
int radius = 2;
setRadius( radius ); // Passing by reference is done in the same way as by value, the difference is the method signature -> setRadius( int &radius );
int &radiusRef = radius;
radiusRef = 3;
std::cout << radius << std::endl; // > 3
To answer what to use. Depends on your types and what you need.
//If you use a setter with reference, like
void setRadius( int& radius );
//You cannot pass literal values like
setRadius( 2 );
setRadius( int(2) );
//Only variables/lvalues
int radius = 2;
setRadius( radius );
If you are using a more complex structure then the reference, or a pointer, makes more sense. It's also more efficient to use a reference than it is to copy a huge structure.
The same applies when returning values. If you don't want the user to change the value of your attribute, then a pointer or reference are not the best option. But you could always use a const pointer or reference,
const int *getRadius() const;
const int &getRadius() const;
To prevent the user from changing the radius from outside, yet be able to use the value. The last const means that this function can be called even if you're using a const Circle, or const *Circle or const &Circle.
I'd say for ints you could just use copies, but for more complex structures, like the Circle, consider using references or pointers. In your case, you even store pointers to the next Circle, so a pointer should do.
class Circle{
public:
void SetRadius(int const& value){ radius = value;} // 1
int GetRadius() const {return radius;} // 2
void SetCircle(std::shared_ptr<Circle> const& pCircle) { next = pCircle;} // 3
std::shared_ptr<Circle> GetCircle() { return next; } // 4
private:
int radius;
std::shared_ptr<Circle> next;
}
1 and 3 This is how you write set functions. Period.
2 and 4 Return by value and dont break the encapsulation
3 and 4 NEVER use raw pointers
I am trying to create an object and everytime I create an object, I then store that object in a static class variable that is an array of all of the objects created.
I am new to c++ and have no idea how to accomplish this. I have done it in Java before, but I am stuck here.
Take this for example purposes:
class Rectangle
{
private:
int width;
int length;
// Code to create an array of Rectangle Objects
// that hold all the the Rectangles ever created
public:
Rectangle();
Rectangle(int x, int y);
};
Rectangle::Rectangle()
{
width = 0;
length = 0;
// code to add an instance of this object to an array of Rectangle Objects
}
Rectangle::Rectangle(int x, int y)
{
width = x;
length = y;
// code to add an instance of this object to an array of Rectangle Objects
}
Is this possible?
Since you have to use an array to keep all objects you have to define a constant maximum size, since the size of an array is fixed and cannot be changed. This means that you also have to define a variable that keeps track of how many elements the array has, so that you don't exceed its boundaries.
const int MAX_SIZE = 100;
class Rectangle
{
private:
int width;
int length;
static Rectangle* all_rectangles[MAX_SIZE];
static int rectangle_count;
public:
Rectangle();
Rectangle(int x, int y);
};
Then you define the static variable and add the objects to the array in the Rectangle constructor, for example:
//Define static variables
Rectangle* Rectangle::all_rectangles[MAX_SIZE];
int Rectangle::rectangle_count = 0;
//Constructor
Rectangle::Rectangle () {
all_rectangles[rectangle_count] = this;
rectangle_count++;
}
Since the array with rectangles (and its components) is private, you can only reach it from within the class. You can however define functions that are public, to reach the rectangles private variables. You can get the width of a rectangle by declaring a function
static int getWidth(int a){
return all_rectangles[a]->width;
}
and call it by cout << Rectangle::getWidth(2) // Get width of second element in array
However vectors are preferable to use before arrays since they are expandable and includes many build-in functions, such as add and remove elements.
Nowadays we tend to avoid plain array and normal pointers.
So go for smart pointers and STL containers.
As your objects will live and die, a vector may not be soon sparse, having lots of holes corresponding to the (deleted) objects you do not use anymore.
Another solution would be an unordered map (hash table). We then need a key. We will not think about transforming the value of a (the this) pointer to a int or long as it is a very dangerous way to go.
So we must pay for some unique id ( see boost uuid ). This is also costly for the computing time but all this mechanism will save you time ( for writing code documentation ).
We then need a smart pointer.
As you want to keep track of all the object created we will go for a mandatory "factory" function to create your objects. As they may not be uniquely owned the only choice left for the factory function is to reject a shared pointer.
This is not directly a shared pointer that may be stored inside our container as it would prevent us to easily get rid of the object once not needed anymore ( the shared pointer inside the container would still participate to the object count ).
Shared pointer may get a custom deleter that will let us do some housekeeping for the container
So this is a weak pointer ( that do not participate to the object count ( or in some very small extent( weak count ) ) that is chosen for our container.
Here is some code ( forgive me I chose widget and not rectangle ):
Our class that must inherit from this curious class ( e.g see Scott Meyers new book Effective Modern C++ item 19 )
class widget:public std::enable_shared_from_this<widget>
alias ( ~ typedef )
using widget_weakptr_cont_t = std::unordered_map<std::string,std::weak_ptr<widget>>;
using widget_smrtp_t = std::shared_ptr<widget>;
using uuid_t = boost::uuids::uuid;
The factory function
static widget_smrtp_t widget_factory(void);
The container
static widget_weakptr_cont_t widget_cont;
The constructor is private ( you may also prevent all the other form of copy or move construction to strengthen the rule )
private:
widget();
void self_emplace(void);
const uuid_t uuid_tag;
The custom deleter for the shared pointers
auto widgetDeleter = [](widget* pw) {
std::cout << "Widget deleter" << std::endl;
widget::widget_cont.erase(pw->uuid_to_string());
delete pw;
if ( widget::widget_cont.empty() )
std::cout << "No Widget left" << std::endl; };
The factory function
widget::widget_smrtp_t widget::widget_factory(void)
{
auto wshp = widget_smrtp_t(new widget(),widgetDeleter);
wshp->self_emplace();
return wshp;
}
The self_emplace function
void widget::self_emplace(void)
{
widget::widget_cont.emplace(uuid_to_string(),shared_from_this());
}
You may then use your factory function inside some other functions ( or main( ) )
auto pw = widget::widget_factory();
An example for retrieving our object from the container could be
for ( auto const & it : widget::widget_cont )
{
//if interested by uuid we normally do
// std::cout << it.first << std::endl;
//For exercice we do the following:
auto shp = it.second.lock();
if ( shp )
{
std::cout << shp->uuid_to_string() << std::endl;
}
}
In the execution below the function func ( not displayed here the post is already too long )
only makes a copy of a globally factored shared pointer (to one of our widget).
The container is not modified by what happened inside func.
func2 creates another local widget that is destroyed when leaving func2. container is shown at these 2 steps.
Finally the globally constructed widget is only destroyed at the end (of the main )
Hello world!
Widget elems are:
84871b52-0757-44c1-be23-fb83e69468c0
func
Widget elems are:
84871b52-0757-44c1-be23-fb83e69468c0
func2
Widget elems are:
b2aedb78-8bb0-427e-9ada-fce37384f7de
84871b52-0757-44c1-be23-fb83e69468c0
Widget deleter
Widget elems are:
84871b52-0757-44c1-be23-fb83e69468c0
bye !
Widget deleter
No Widget left
I hope all of this may help
NGI
EDIT 2016.08.21
I publish the "unabridged code" Code on Coliru
It will not be much clearer because when I first replied I tried also other syntax features just for test.
Anyway you have now all in hands ( sometimes I do not publish a full code in order to avoid the "homework" copy/paste problem )
Lately I tried to simplify my code without success, 2 thoughts:
class widget:public std::enable_shared_from_this < widget > { ... }; is already a CRTP
You can not use shared_from_this() when there is no shared_ptr < T > already existing SO: shared_from_this() causing bad_weak_ptr exception
I'm making a game with SDL that used libconfig to read some settings from a file. The problem is that I made a class called ClipList that contains a std::vector<SDL_Rect> to store the settings but when trying to add SDL_Rect objects to the vector, for some reason push_back does nothing and I end up with an empty vector.
This is the class:
class ClipList
{
public:
ClipList();
ClipList(int);
virtual ~ClipList();
void addClip(int,int,int,int);
void getClip(int,SDL_Rect*);
int getLength();
protected:
private:
std::vector<SDL_Rect> clips;
};
ClipList::ClipList(int l)
{
clips.reserve(l);
}
void ClipList::addClip(int x,int y,int w,int h){
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
clips.push_back(rect);
}
void ClipList::getClip(int i,SDL_Rect* rect){
rect = &(clips.at(i));
}
int ClipList::getLength(){
return clips.size();
}
And this is the function where I initialize the ClipList object. This function gets called from main.
void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips){
const Setting& root = placlips->getRoot();
int x,y,w,h;
try{
Setting& clipsett = root["clips"];
int cliplen = clipsett.getLength();
clips = new ClipList(cliplen);
flipclips = new ClipList(cliplen);
for(int i=0;i<cliplen;i++){
const Setting& c = clipsett[i];
if(!(c.lookupValue("x",x)&&c.lookupValue("y",y)&&c.lookupValue("w",w)&&c.lookupValue("h",h))){
continue;
}
clips->addClip(x,y,w,h);
}
}catch(const SettingNotFoundException &nfex){
cerr << "Setting not found at" << nfex.getPath() << endl;
}
}
Regardless of whether the ClipList objects get initialized in main or set_clips, clips.push_back(rect) doesn't work. The capacity of the vector changes but no object gets stored so I end up with a segfault if I try to do anything else with the vector, even checking if the vector is empty or not.
I am going to guess, the signature of the function
void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips);
is the culprit. You are allocating memory for clips and flipclips in this function but since the pointers are passed by value, the calling function does not see the allocated memory.
If you change the function signature to:
void set_clips(Config* placlips, ClipList*& clips, ClipList*& flipclips);
your problems should go away.
clips.push_back(rect) is working fine. Your set_clips function allocates new ClipList instances but does not pass those pointers back to the caller. The caller is probably attempting to use a garbage pointer as an initialise instance and that is why you are getting a segfault.
You need to pass the created objects back. You should use something like std::shared_ptr<> to do that instead of bare pointers.
Update on how to do this without using std::shared_ptr<>:
You need to keep track of ownership and deal with exceptions. In terms of the actual passing, the rule I use (originally from Lakos in "Large Scale C++ Software Design") is that parameters that are return values (as you are attempting to use them) are pointers, and read-only parameters are by value or const-reference. Return values come first.
So, your set_clips function should look like this:
void set_clips(ClipList** clips, ClipList** flip_clips, Config const& placlips)
When you call set_clips you pass a pointer to each pointer that will receive the allocated value, and pass a const-reference to the placlips object that is not modified by the function.
You would all it something like this:
ClipList* clips = 0;
ClipList* flip_clips = 0;
set_clips(&clips, &flip_flips, placlips);
// ... then do whatever comes next.
But combining those rules with std::shared_ptr<> or boost::shared_ptr<> is better and the "modern C++" style.
I'm currently pondering how should I go about making a 2D vector array for a sort of a game board.
The board should be vectors because the size can vary, and each "square" should contain information about what objects are in that square.
The problem is that there can be overlapping objects, and the objects may not be the same type or class.
This is what I'm currently considering: (pseudo code)
struct Square {
vector<enum type>;
vector<pointers to objects>;
};
vector< vector <Square> >;
And the pointer's would point to different vector arrays each holding specific objects.
I'm unsure how to make such functionality or if this is even possible, and I'm seriously thinking this might be more complicated then it needs to be..
Some objects must be classes, but I could make all the types of objects in the game board classes that inherit from one master class.. But in the end the objects are completely different so I'm not sure if that makes much of a difference.
Am I just being blind and missing a easier way to do what I'm trying to do: 2D array holding different types of elements that can also overlap in the array?
I'd really appreciate any help, snippets or insight.
Notes:
Board size won't chance after creation.
Objects must be able to move around in the board.
Here's what I would suggest.
#include <boost/shared_ptr.hpp>
class GameObject {
public:
virtual ~GameObject() {}
enum Type {
FOO,
BAR
};
virtual Type type() const = 0;
virtual std::string name() const = 0;
virtual void damaged() {}
};
class FooObject : public GameObject {
public:
Type type() const { return FOO; }
std::string name() const { return "Foo object"; }
void damaged() {
std::cout << "Foo was damaged!" << std::endl;
}
};
class BarObject : public GameObject {
public:
Type type() const { return BAR; }
std::string name() const { return "Bar object"; }
// Bar object doesn't respond to damage: no need to override damaged()
};
class Square {
std::vector<boost::shared_ptr<GameObject> > objects;
};
class Board {
// Details of the implementation here not important, but there
// should be a class to hide them.
Square* squares;
int width, height;
Board(int width, int height) :
squares ( new Square[ width * height ] ),
width ( width ),
height ( height )
{
}
~Board() {
delete [] squares;
}
Square& square(int x, int y) {
if( x < 0 || x >= width || y < 0 || y >= height ) {
throw std::logic_error( "accessed square out of bounds" );
}
return squares[ x + width * y ];
}
};
Summary:
Have a single base class for all sorts of objects that can be placed on a game board.
A class of this type must have a virtual destructor, even if it's trivial. This is because you will be deleting things through GameObject pointers.
If it's necessary to distinguish the game objects, use a virtual method returning a 'type' value.
As far as it's not necessary to use it, don't use that type value, but use other virtual methods that do meaningful things instead. Using the type value (and then generally casting to the subtype) should be considered a last resort. For instance (inventing details about your game freely):
Every object has a name that shows when you put the cursor over it. This is returned in name().
Events in the game may cause 'damage' an object. This only applies to some sorts of objects, so the default action on damaged() is to do nothing. Foo-objects, which respond to damage, override this with an actual action.
However you implement the board, hide your exact implementation away in a class. (Don't take my code as an indication that you shouldn't use vector<> for this, that's definitely fine. I have a slight personal preference against vector< vector<> > here, but that's not too bad either.)
Use shared pointers for the game objects.
Boost has a great and widely used implementation.
If you can't use shared pointers, control the lifetime of your game objects outside the Square class (say, in a master list of all game objects in the Board class), and then use raw pointers in the Square class.
If you do use shared pointers, and it's the first time you do, briefly read up on them first. They're not magic, you need to beware of certain things such as circular references.
Depending on your needs, you may want to have a "backlink" in GameObject to the squares, or the coordinates of the squares, that contain pointers to that GameObject. This will allow you to easily remove objects from the board and move them around.
Guys, I am very new to c++. I have just wrote this class:
class planet
{
public:
float angularSpeed;
float angle;
};
Here is a function trying to modify the angle of the object:
void foo(planet* p)
{
p->angle = p->angle + p->angularSpeed;
}
planet* bar = new planet();
bar->angularSpeed = 1;
bar->angle = 2;
foo(bar);
It seem that the angle in bar didn't change at all.
Note that you are passing bar by pointer, not by reference. Pass-by-reference would look like this:
void foo(planet& p) // note: & instead of *
{
p.angle += p.angularSpeed; // note: . instead of ->
}
Pass-by-reference has the added benefit that p cannot be a null reference. Therefore, your function can no longer cause any null dereferencing error.
Second, and that's a detail, if your planet contains only public member variables, you could just as well declare it struct (where the default accessibility is public).
PS: As far as I can see it, your code should work; at least the parts you showed us.
Appearances must be deceptive because the code should result in foo(bar) changing the contents of the angle field.
btw this is not passing by reference, this is passing by pointer. Could you change the title?
Passing by reference (better) would be
void foo(planet& p) {
p.angle += p.angularSpeed;
}
planet bar;
bar.angularSpeed=1;
bar.angle=2;
foo(bar);
You might also consider a constructor for planet that takes as parameters the initial values of angle and angularSpeed, and define a default constructor that sets them both to 0. Otherwise you have a bug farm in the making due to unset values in planet instances.