Hi guys!
I have a class Dinosaur and it has its own fields. I have another class cages. In the cage lives the dinosaur. So in the cage class I created Dinosaur* f_dinos. Then I have another class where I want to have the cages with the dinos. Do I have to use Cage** f_cages or Cage* f_cages?
The point of encapsulation and abstraction is that you can stop caring about what is happening inside an object and simply use it, so to answer your question: Cage* f_cages.
Consider using a C++ container such as std::vector instead of a pointer to a dynamic array, and a smart pointer instead of a raw pointer when working with a single object.
Can you give me more explanation why I gotta use only one*
You want an array of "Cage" objects, yes?
So it doesn't matter if a Cage object contains dinosaurs, or bears, or one huge elephant. All that matters is that some "Cage" object exists, and you want to make an array of Cages.
1 2 3 4
Cage* cages = new Cage[n]; // n cages
cages[0].f_dinos = new Dinosaur[m]; // m dinosaurs in the first cage
// ...
delete [] cages[0].f_dinos;
As FurryGuy mentioned, you could just use vector<YourObject>, and also probably avoid pointers.
Can you give me more explanation why I gotta use only one*?
The reason why you only need one * is because the Cage is already a pointer at the end of the day. Think of it like this. Let’s assume that a Dino is just a string.
1 2 3 4 5
typedef std::string Dino; // every Dino is just a string. (Dino == std::string)
typedef Dino* Cage; // every Cage is just a pointer to a Dino, which is just a string. (Dino* == std::string*)
typedef Cage* Zoo; // every Zoo is just a pointer to a Cage, which is just a pointer to a Dino, which is just a pointer to a string. (Cage* == Dino** == std::string**)
So in the end, the code still turns out to be a Dino** technically, but you don’t have to specify the extra *, because it’s provided/implied.
So, Zoo == std::string**
Hope that helps some.
Edit: hm. Sorry I seem to have provided a slightly indirect way of saying that, here’s the same example with classes instead of typedef.
1 2 3 4 5 6 7 8 9 10 11
class Dino {
std::string data;
}; // every Dino is just a string. (Dino == std::string)
class Cage {
Dino* data;
}; // every Cage is just a pointer to a Dino, which is just a string. (Dino* == std::string*)
class Zoo {
Cage* data;
}; // every Zoo is just a pointer to a Cage, which is just a pointer to a Dino, which is just a pointer to a string. (Cage* == Dino** == std::string**)
That's just restating what you've already told us. Can you explain to us why you believe that to be the case? What have you understood (or misunderstood) about pointers and arrays, that leads you to believe that?
So a pointe of poniters is like a dynamic matrix and I thought that I will have pointer of pointers, like the matrix I will have rows of cages and in every row I will have pointers of Dinos. I just imagine it like that but maybe I am wrond.
The difference is that they are two separate objects.
A matrix can directly have an int** point to it. (**matrix) would first dereference once to get you a (int*) and then dereferencing it again gets you the actual int.
But in your case, you don't have an array of arrays of Cages or an array of arrays of Dinos.
You have an array of Cages. That's it. An array of Cages.
It just so happens that inside a Cage, you can also have an array of Dinos. But you still just have a single 1-dimensional array of cages. And then each Cage has a single 1-dimensional array of cages.
(**cages) doesn't make sense. (*cages) would get you the first cage, which then has a member like f_dinos, so you'd do something like: cages[3].f_dinos[5] // 4th cage, 6th dino in 4th cage
So a pointe of poniters is like a dynamic matrix and I thought that I will have pointer of pointers, like the matrix I will have rows of cages and in every row I will have pointers of Dinos.
No. You don't have a "dynamic matrix" (by which I assume you mean a 2-dimensional array) of anything. You have a 1-dimensional array of Cage objects, and a pointer to the first object in the array.
What do you think would happen if you de-referenced that Cage** f_cages pointer twice? What type of object would you get? Where in memory would that object be found?
I just imagine it like that but maybe I am wrond.
I understand why, conceptually, it feels a bit like you could imagine it as a 2-dimensional matrix. But if you think the compiler can look inside your head and see what you're imagining, then you've very much misunderstood how compilers work.
It sounds to me like you don't really understand what pointers are, or how they relate to arrays. I'd strongly recommend re-reading your textbook, or whatever tutorials you're using, because they're absolutely crucial to C programming, and important in C++ programming too.
Okay so if I have f_cages[3].f_dinos[i] how I can know how many dinos I have in a specific cage? Like in the example in cage number 4 how many dinos do I have?
Arrays don't keep track of their own sizes. You have to do it yourself with a separate variable.
Or, you could use vectors, which have a .size() function.
Can I do it with a getter? Like do a getter in the dino class and it will always be =1 /every dino on their own is only one/, then have a
for(int i=0; i<MAX_CAPACITY_FOR_THE_CAGE; i++){
counter+=Cage[the number of the particular cage].dino[i].getNumber;
}
Can I do it like that?