int main()
{
//Is this correct?//this seems to work
Square <double>* sqr = new Square<double> (3.14);
cout << sqr->getSide() << endl
Square <double>* sqrX = new Square<double> [4];
//this not works, because I dont' have the default constructor
//but I would like to use the current constructor I've defined.
//I mean, I would like to call the constructor I've defined to initialize all the 4 objects
return 0;
}
Square<double> sqr(3.14);
std::vector< Square<double> > sqrX;
sqrX.reserve(4);
//when you know how you want to construct the object
sqrX.push_back( Square<double>(2.79) );
But shouldn't sqrX.push_back () just append 1 element at the end of the sqrX ?
So actually we have just a vector with one templated class?! To have 4 or 5 or whatever we want, we have to use a loop!
Is it necessary to reserve the area? (because I have just seen that push_back() reallocates memory automatically...)
So the code could be:
1 2 3 4 5
int LEN = 5;
vector< Square<double> > sqrX;
//sqrX.reserve(5);//it s not necessary
for (int i=0; i< LEN; i++)
sqrX.push_back( Square <double> (2.79) );
#include <vector>
#include <new>
template <class t>//templated class
class Square
{
public:
t side;
//inline constructor
Square(t side){ this->side = side; }
~Square() { }
t getSide();
};
int main()
{
constunsigned num_elements = 4;
{
// manually:
void* raw_memory = operatornew(sizeof(Square<double>) * num_elements);
Square<double>* sqr = static_cast<Square<double>*>(raw_memory);
// construct each of the 4 squares:
for (unsigned i = 0; i < num_elements; ++i)
new (sqr + i) Square<double>(i*3.14);
// use the Squares here
// then, what was constructed must be destructed:
for (unsigned i = 0; i < num_elements; ++i)
(sqr + i)->~Square<double>();
// and the memory deallocated.
operatordelete(sqr);
}
//using std::vector:
{
std::vector<Square<double>> sqr;
for (unsigned i = 0; i < num_elements; ++i)
sqr.emplace_back(i*3.14);
// use the squares here...
// then the objects are automatically destructed and
// memory freed when sqr goes out of scope.
}
}
Thank you! Yes, I find that vector is a nice and useful templated class and a good header.
Why it is necessary to use the keyword "operator" before new and delete? In the first case we could replace the "operator new" simply with malloc, right?
I can't really understand the syntax at line 29:
new (sqr + i) Square<double>(i*3.14);
Trying to understand things...
You have to number the objects you are allocating with (sqr + i) ? Would you do the same thing with "normal" classes, right?
outside our dare main
1 2 3 4 5 6 7 8 9
class Square
{
int side;
//...
public:
~Square(){};
Square(int side = 1) { //... }
};
in main function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int num_objs = 4;
void* raw_memory = operatornew ( sizeof(Square)* num_objs );
Square* sqr = static_cast<Square*>(raw_memory);
for(int i = 0; i<num_objs; i++)
new (sqr + i) Square (i);//I don't understand very well this syntax...
//do what I want...
for(int i = 0; i<num_objs; i++)
(sqr + i)->~Square();
operatordelete(sqr);//Are we using "operator"+delete like free(sqr)?
//shoudn't we deallocate also the memory for raw_memory?
//operator delete(raw_memory);
You have to number the objects you are allocating with (sqr + i) ? Would you do the same thing with "normal" classes, right?
That is simple pointer arithmetic. I could've written: new (&sqr[i]) Square(i*3.14); The second question makes no sense to me.
1 2
//shoudn't we deallocate also the memory for raw_memory?
//operator delete(raw_memory);
No. sqr and raw_memory point to the same piece of memory. You don't want to free the same piece of memory twice, however we could've used operator delete on raw_memoryinstead ofsqr.
But if I use new Foo[5]; I am not calling the singles constructors (just allocating memory for 5 constructors, right?)
And if we wanted to initialize the objects (with another constructor)? Should we do like your first example: allocating memory first to all the objects and then create the objects singularly?
Something like this?
1 2 3 4 5 6
int num_objs = 5;
Foo* f1 = (Foo*)malloc( sizeof(Foo)* num_objs);
for (int i=0; i<5; i++)
new (f1 + i) Foo(i);
But if I use new Foo[5]; I am not calling the singles constructors (just allocating memory for 5 constructors, right?)
No, not right. The expression new Foo[5]; allocates space for 5 Foo objects and default constructs them.
And if we wanted to initialize the objects (with another constructor)? Should we do like your first example: allocating memory first to all the objects and then create the objects singularly?
Something like this?
Right now, I think you should move on to other things and come back to this when you've had more exposure to the language. This isn't the easiest facet of the language to understand. (And, no, that code does not cause undefined behavior like the previous did.)
I would like to understand things. This is not difficult, I just have little experience and have read just a few things about the topic. You don't have to get angry! I don't have to use containers and give up to understand things more complicated (to be ignorant).
Ok, so with the expression new Foo[5] we are of course allocating memory for 5 objects of type Foo and we are also initializing them, calling the default constructor, as you said.
So the difference between this code:
1 2 3
Foo* f1 = (Foo*)malloc( sizeof(Foo)* num_objs);
for (int i=0; i<5; i++)
new (f1 + i) Foo(i);
and this other:
1 2 3
Foo* f1 = new Foo[5];
for (int i=0; i<5; i++)
new (f1+i) Foo ();//or new (&f1[i]) Foo();
is that the first case we are not calling, with the expression:
Foo* f1 = (Foo*)malloc( sizeof(Foo)* num_objs);
, the constructors for the single objects of type Foo, we are just ofc allocating memory, so there's no undefined behavior, instead in the second case we call the objects constructors twice.
So could we call another constructor with the first piece of code?
1 2 3
Foo* f1 = (Foo*)malloc( sizeof(Foo)* num_objs);
for (int i=0; i<5; i++)
new (f1 + i) Foo(/*another constuctor*/);
You don't have to get angry! I don't have to use containers and give up to understand things more complicated (to be ignorant).
What makes you think using containers means you're giving up or will remain ignorant? I say you need to come back to this later because you keep asking the same question over and over.
zwiluwu wrote:
So could we call another constructor with the first piece of code?
Yes. See the very first piece of code I posted. That is what started this entire line of questioning, remember?
I am not asking the same thing again and again, if I ask things similar between them it's because you can't respond unambiguously and completely!!!
Yes. See the very first piece of code I posted. That is what started this entire line of questioning, remember?
Dude, the first piece of code you posted was about templated classes, I remembered exactly from where this all began. Then I began to ask about non-templated classes, remember? You couldn't distinguish things, even if things are equal, you have to specify that they are! If you didn't understand my questions, it's another discussion!