I am quite new to C++ so forgive me, if the mistake is stupid. I am currently working on a class, that can save single characters (only one of each) and do some simple operations.
The problem I am having seems to be in the constructor of the class. Since I only have characters I am using a bool array of the size 256. So if I wanted to add the character "A" to my array I would simply flip array[64] to 1.
To use the array in the way I want to I initialized it with zeros for every index. So it looks like this:
Set<char>::Set() {
bool _elements[256] = {0};
}
If I check all the values of the member variable _elements now it does not only contain zeros. I don't know what might be causing this. There are no other function calls or anything in between.
Set set;
for (int i = 0; i < 256; i++) { printf("%d\n", set._elemens[i]; }
You're initializing a local variable _elements inside the constructor, it will be destroyed when get out of the constructor, and has nothing to do with the member variable _elemens. (And note the name is not same.)
You can initialize the member variable by member initializer list:
Set<char>::Set() : _elemens {0} {}
or in-class brace-or-equal initializer (I don't know how Set is declared so just as an example):
struct Set {
bool _elemens[256] = {0};
};
And as #M.M pointed, for both cases just {} would work well (all of the elements will be set to false) and be preferable for your case.
The array _elements is a local variable to Set() constructor. You're not supposed to be able to access it outside the Set() constructor.
The way you want to use it, you need the _elements to be a public member variable to class Set.
Related
Consider an array of function pointers within a class in c++14:
class myClass {
myClass();
void (* myFunctions [5])();
}
This array will be populated in other parts of the code, and it is not guaranteed that the array will actually hold as many function pointers as it can (5 in the example). So before calling any of the functions referred to by the array i'd need to check whether the pointer I'm trying to use actually stores something. My idea was to compare the pointer against nullptr, and assume that it points to a valid function if the test fails, i.e. in some function of that class:
if(myFunctions[x] == nullptr) {
// Handle error
return;
}
// Use myFunctions[x]
I was wondering if I need to initialize the array before making that kind of speculation. How is this array initialized if I only write the above two lines of code? Can I assume something like myFunctions[x] == nullptr is true in that case? Or do I need to do an explicit initialization like the following one?
for(int i = 0; i < dimension; i++)
myFunctions[i] = nullptr;
I've found the zero initialization page on cppreference.com, but as I'm learning c++ and I'm still very unexperienced I wasn't able to understand whether this applies in my case. I've also tried to test the pointers by printing their value without assigning any function address and got 0 0 0 0 0, but I don't think the result is reliable: this program is for a microcontroller, and it's possible that the "garbage" values on the stack are all 0s since it is emptied during each code upload.
I don't think that you have to initialize the array, although I'd encourage you to do that. The reason why the array is default-initialized in your case is because you provide a constructor and do not mention the data member in the initializer list (cf. cppreference/default initialization):
Default initialization is performed in three situations:
...
3) when a base class or a non-static data member is not mentioned in a
constructor initializer list and that constructor is called.
Hence, default initialization will take place.
Anyway, in order to express that you rely on a data member to be "zero" without enforcing in other ways that non-initialized entries will not be accessed, I'd make the initialization explicit, e.g.
class myClass {
myClass();
void (* myFunctions [5])() = { };
}
Before I put my question let me mention in advance that I am aware that this topic has been discussed a lot, but yet again by looking to most of the answers I failed to figure out the proper way to achieve what I want (most probably because I missed sth from the anwers given).
So, say I want to create 20 times a vector of objects (say of size ten each) that should be of global scope (in the sense that this is done inside a class and i want these vectors of objects to be passed outside the class).
So, I am really not sure if the following is valid:
for ( int i =0; i<20; i++)
vector<A> * vec_of_class = new vector<A>(10);
/*where A is the class and I use new to have them in the heap,
so that they won't be local */
Now, I know that this means that I should be extra carefull with handling them
and make sure that I preper delete them, but I am not sure if the operation I am doing is valid. In general I want to achieve to initialize 20 different vectors of object A that can be used in the global scope (the operation is happening inside a function of an other class), I know that it could be used
a vector of vectors of object A, but I would like to find out how to do correctly this kind of operation (initializing 20 different vectors of object A inside the body function of an other class and use them globally).
I hope ,my question was not to confusing and you could give me some help here.
There should never be a case when you dynamically allocate any standard container, including vector. So std::vector<> = new <> is always wrong.
To initialize your vector, you can use multitude of techniques. I find initializer lists especially handy, like here:
std::vector<int> vec{10, 20, 30, 40, 50};
So, say I want to create 20 times a vector of objects (say of size ten each)
That's easy. Use:
std::vector<std::vector<A>> my_data{20, std::vector<A>{10}};
that should be of global scope (in the sense that this is done inside a class and i want these vectors of objects to be passed outside the class).
I don't have a clear picture of what you want to accomplish here.
When something is done inside a class, it could be done in a static member function or a regular member function. It seems like you should use a static member function but I am not sure.
If you use a static member function, I would suggest:
std::vector<std::vector<A>> const& TheClass::get_my_data()
{
static std::vector<std::vector<A>> my_data{20, std::vector<A>{10}};
static bool inited = false;
if ( !inited )
{
// Set the values of the elements in my_data
// ...
inited = true;
}
return my_data;
}
If you use a regular member function, I suggest populating my_data in the constructor and returning from a function.
// Need to make my_data a member variable
TheClass::TheClass() : my_data{20, std::vector<A>{10}}
{
// Set the values of the elements in my_data
// ...
}
std::vector<std::vector<A>> const& TheClass::get_my_data() const
{
return my_data;
}
If you declare a variable into a function, the scope of that variable will be the function. It won't be accessible from outside.
What you can do is declare the 20 pointers in the global scope, and initialize them wherever you want (inside a function, for instance).
I'm curious if these are zero initialized and all my pointers are 0 when I declare a fixed size array. I can say foo* arr[1000][1000] and I see that all the entries are 0..but I am not sure if this is something I can rely on or not. I could say foo* arr[1000][1000] = {} but this double array is a member variable in a class and I wouldn't want to have a double for loop in the constructor if it's not necessary...
Depends on how you allocate the array.
If it's static or global, then the contents will all be initialised to 0. If it's a local variable, then the contents won't be initialised to anything.
So since your array is a member variable, it won't be initialised to 0 automatically. However, you can initialise all the variables to zero by using the initialisation list in the constructor thusly:
struct A {
// VVV value-initialises the contents of arr
A() : arr() { }
double arr[x][y];
};
It depends on the context. If the array is defined at namespace level, then static initialization will set all pointers to null for you. If it is defined in a function scope or as a member of a class, there is no such guarantee.
Since it is a member of a class, it will not be correctly initialized, so you will need to initialize it manually. You can do so by adding arr() to the initialization list. Being pointers, you can use memset to set the whole array to 0 in a single call (which will also be as efficient as it gets), but beware, this only works for POD types.
I have an array of structs -
struct MagicalUnicornBullets {
PS2Sprite SparklyUnicornBullet();
bool onscreen;
};
MagicalUnicornBullets MagicalUnicornBullets[25];
I want to loop through the array, and initialise the contents of the struct.
Obviously, this is just the case of a for loop, and for the bool it's simply onscreen = false; but how would I initialise the SparklyUnicornBullet?
Right now my code is -
MagicalUnicornBullets[i].SparklyUnicornBullet.ScaleAbsolute(4,4);
I'm well aware this is wrong - but how do I access the class functions when they're within the Struct?
Realize that SparklyUnicornBullet is actually a member function which returns a PS2Sprite object. This returned PS2Sprite has a member function ScaleAbsolute which you want to call. So your code above is nearly correct. You are simply missing ()'s:
MagicalUnicornBullets[i].SparklyUnicornBullet().ScaleAbsolute(4,4);
That said, there's a number of things that's bad with your code. For one, you are declaring an array that has the same name as an object:
MagicalUnicornBullets MagicalUnicornBullets[25];
I think this is allowed, but it is so evil and malmotivated that I can't even say that for certian, because I would reject any such code regardless of it's motivation or legality. You should give the array a different name:
MagicalUnicornBullets bullets[25];
Next, your initialization loop is unneeded. The code:
MagicalUnicornBullets MagicalUnicornBullets[25];
creates a C-style array of 25 MagicalUnicornBullets by calling each one's default constructor. So the easiest thing to do is to simply provide a default constructor that does what you want:
struct MagicalUnicornBullets {
MagicalUnicornBullets();
// ...
};
MagicalUnicornBullets::MagicalUnicornBullets()
: onscreen(false)
{
SparklyUnicornBullet().ScaleAbsolute(4,4)
}
Now there's no need for a loop at all. All 25 will be constructed and initialized the way you want.
Finally, usually in C++ it's advantagerous to not use a C-style array at all, but a collection class such as std::vector.
Well, I'm gonna be pretty straightforward here, I just have a piece of code in c++ which I'm not sure I really understand and need some help with.
Ok, to simplify lets just say I have a class that is defined like this: (the real class is a little bit more complicated, but this is what matters)
class myClass : public Runnable {
Semaphore *m_pMySemaphore;
__Queue<Requests> *m_pQueue;
Request m_Request;
VetorSlotBuffer *m_vetorSlotBuffer;
}
Up to here nothing is wrong, myClass is just a regular class which has 3 members that actually are pointers to other classes and an object of the class Request, the implementation of those classes not being important for my point here.
Then when this person implemented the constructor for myClass he or she did this:
myClass::myClass() : m_pMySemaphore(0), m_pQueue(0), m_vetorSlotBuffer(0) {
}
It's pretty evident that those three variables are treated like that by the constructor because they are pointers, am I right? but what kind of syntax is that? am I setting the pointers to null by doing that? I've seen a little bit of c++ already but never found something like that.
And secondly, what's the deal with the ":" after the constructor declaration? that I've seen but never took the time to investigate. Is this like an inner class or something?
Thank you very much in advance.
Nelson R. Perez
This is an initialization list
And it's the recommended way to initialize your members
It's member's initialization on object creation, called initialization list.
You can't initialize them elsewhere, say:
class X {
int i = 0; // error bad syntax
}
Neither in constructor by use of assignment, if they're const :
class X {
const int i;
X(){
i = 0; // error it's a const
}
}
So the c++ guys made up that syntax!
Yes, those pointers are being initialized to NULL. The key thing here is that they are initialized, as opposed to assigned. I.e.:
myClass::myClass()
: m_pMySemaphore(0), // initialized to 0
m_pQueue(NULL) // initialized to NULL (preferable to 0)
// no initializer for m_Request - uses default constructor
// no initializer for m_vectorSlotBuffer
{
// at this point, the object is entirely initialized, and can be used.
// this next line ASSIGNS to the member
m_vectorSlotBuffer = 0;
}
What happens to m_vectorSlotBuffer, is that it is initialized, and then assigned, in two separate steps. By doing it like m_pQueue, we save a step, and initialize properly. This becomes very important when we want to use non-default constructor, or if we want to initialize const members.
Also, the : after the constructor () is what begins the initialization section, before we get to the { where we enter the body of the constructor.
Finally, NULL is not guaranteed to be 0. NULL is portable, but most architectures use 0 as NULL.
EDIT: 0/NULL distinction is not meaningful anymore. Just pick one and be consistent.
Yes, pointers set to 0 are pointers set to null.
The : syntax for constructors is called initialization lists. It's used here for initializing member fields in a simple, direct manner. Should be easy to google with the proper terminology.