this is a really simple question but I havn't done c++ properly for years and so I'm a little baffled by this. Also, it's not the easiest thing (for me at least) to look up on the internet, not for trying.
Why doesn't this use the new keyword and how does it work?
Basically, what's going on here?
CPlayer newPlayer = CPlayer(position, attacker);
This expression:
CPlayer(position, attacker)
creates a temporary object of type CPlayer using the above constructor, then:
CPlayer newPlayer =...;
The mentioned temporary object gets copied using the copy constructor to newPlayer. A better way is to write the following to avoid temporaries:
CPlayer newPlayer(position, attacker);
The above constructs a CPlayer object on the stack, hence it doesn't need new. You only need to use new if you are trying to allocate a CPlayer object on the heap. If you're using heap allocation, the code would look like this:
CPlayer *newPlayer = new CPlayer(position, attacker);
Notice that in this case we're using a pointer to a CPlayer object that will need to be cleaned up by a matching call to delete. An object allocated on the stack will be destroyed automatically when it goes out of scope.
Actually it would have been easier and more obvious to write:
CPlayer newPlayer(position, attacker);
A lot of compilers will optimise the version you posted to the above anyway and it's clearer to read.
CPlayer newPlayer = CPlayer(position, attacker);
This line creates a new local object of type CPlayer. Despite its function-like appearance, this simply calls CPlayer's constructor. No temporaries or copying are involved. The object named newPlayer lives as long as the scope it's enclosed in. You don't use the new keyword here because C++ isn't Java.
CPlayer* newPlayer = new CPlayer(position, attacker);
This line constructs a CPlayer object on the heap and defines a pointer named newPlayer to point at it. The object lives until someone deletes it.
newPlayer is no dynamically allocated variable but an auto, stack-allocated variable:
CPlayer* newPlayer = new CPlayer(pos, attacker);
is different from
CPlayer newPlayer = CPlayer(pos, attacker);
newPlayer is allocated on the stack via the normal CPlayer(position, attacker) constructor invocation, though somewhat verbose than the usual
CPlayer newPlayer(pos, attacker);
It's basically the same as saying:
int i = int(3);
Related
First i am from JAVA.
In java we create class object like this.
Example example=new Example();
The Example class can have constructor or cannot have constructor.
I can use the same in c++ like this
Example* example=new Example();
Where constructor is compulsory.
From this tutorial http://www.cplusplus.com/doc/tutorial/classes/
I got that we can create object like this.
Example example;
Which do not require an constructor.
I have two questions.
What is the difference between both the way of creating class objects.
If I am creating object like Example example; how to use that in an singleton class.
like I usually do like this.
Sample* Singleton::get_sample() {
if (sample == NULL) {
sample = new Sample();
}
return sample;
}
Please guide me if I am wrong.
I can use the same in c++ like this [...] Where constructor is compulsory. From this tutorial I got that we can create object like this [...] Which do not require an constructor.
This is wrong. A constructor must exist in order to create an object. The constructor could be defined implicitly by the compiler under some conditions if you do not provide any, but eventually the constructor must be there if you want an object to be instantiated. In fact, the lifetime of an object is defined to begin when the constructor routine returns.
From Paragraph 3.8/1 of the C++11 Standard:
[...] The lifetime of an object of type T begins when:
— storage with the proper alignment and size for type T is obtained, and
— if the object has non-trivial initialization, its initialization is complete.
Therefore, a constructor must be present.
1) What is the difference between both the way of creating class objects.
When you instantiate object with automatic storage duration, like this (where X is some class):
X x;
You are creating an object which will be automatically destroyed when it goes out of scope. On the other hand, when you do:
X* x = new X();
You are creating an object dynamically and you are binding its address to a pointer. This way, the object you created will not be destroyed when your x pointer goes out of scope.
In Modern C++, this is regarded as a dubious programming practice: although pointers are important because they allow realizing reference semantics, raw pointers are bad because they could result in memory leaks (objects outliving all of their pointers and never getting destroyed) or in dangling pointers (pointers outliving the object they point to, potentially causing Undefined Behavior when dereferenced).
In fact, when creating an object with new, you always have to remember destroying it with delete:
delete x;
If you need reference semantics and are forced to use pointers, in C++11 you should consider using smart pointers instead:
std::shared_ptr<X> x = std::make_shared<X>();
Smart pointers take care of memory management issues, which is what gives you headache with raw pointers. Smart pointers are, in fact, almost the same as Java or C# object references. The "almost" is necessary because the programmer must take care of not introducing cyclic dependencies through owning smart pointers.
2) If i am creating object like Example example; how to use that in an singleton class.
You could do something like this (simplified code):
struct Example
{
static Example& instance()
{
static Example example;
return example;
}
private:
Example() { }
Example(Example const&) = delete;
Example(Example&&) = delete;
Example& operator = (Example const&) = delete;
Example& operator = (Example&&) = delete;
};
Example example;
This is a declaration of a variable named example of type Example. This will default-initialize the object which involves calling its default constructor. The object will have automatic storage duration which means that it will be destroyed when it goes out of scope.
Example* example;
This is a declaration of a variable named example which is a pointer to an Example. In this case, default-initialization leaves it uninitialized - the pointer is pointing nowhere in particular. There is no Example object here. The pointer object has automatic storage duration.
Example* example = new Example();
This is a declaration of a variable named example which is a pointer to an Example. This pointer object, as above, has automatic storage duration. It is then initialized with the result of new Example();. This new expression creates an Example object with dynamic storage duration and then returns a pointer to it. So the example pointer is now pointing to that dynamically allocated object. The Example object is value-initialized which will call a user-provided constructor if there is one or otherwise initialise all members to 0.
Example* example = new Example;
This is similar to the previous line. The difference is that the Example object is default-initialized, which will call the default constructor of Example (or leave it uninitialized if it is not of class type).
A dynamically allocated object must be deleted (probably with delete example;).
There is two ways to make/create object in c++.
First one is :
MyClass myclass; // if you don;t need to call rather than default constructor
MyClass myclass(12); // if you need to call constructor with parameters
Second one is :
MyClass *myclass = new MyClass();// if you don;t need to call rather than default constructor
MyClass *myclass = new MyClass(12);// if you need to call constructor with parameters
In c++ if you use new keyword, object will be stored in heap. it;s very useful if you are using this object long time of period and if you use first method, it will be stored in stack. it can be used only short time period. Notice : if you use new keyword, remember it will return pointer value. you should declare name with *. If you use second method, it doesn;t delete object in the heap. you must delete by yourself using delete keyword;
delete myclass;
1) What is the difference between both the way of creating class objects.
a) pointer
Example* example=new Example();
// you get a pointer, and when you finish it use, you have to delete it:
delete example;
b) Simple declaration
Example example;
you get a variable, not a pointer, and it will be destroyed out of scope it was declared.
2) Singleton C++
This SO question may helps you
First of all, both cases calls a constructor. If you write
Example *example = new Example();
then you are creating an object, call the constructor and retrieve a pointer to it.
If you write
Example example;
The only difference is that you are getting the object and not a pointer to it. The constructor called in this case is the same as above, the default (no argument) constructor.
As for the singleton question, you must simple invoke your static method by writing:
Example *e = Singleton::getExample();
1)What is the difference between both the way of creating class
objects.
First one is a pointer to a constructed object in heap (by new).
Second one is an object that implicitly constructed. (Default constructor)
2)If i am creating object like Example example; how to use that in an
singleton class.
It depends on your goals, easiest is put it as a member in class simply.
A sample of a singleton class which has an object from Example class:
class Sample
{
Example example;
public:
static inline Sample *getInstance()
{
if (!uniqeInstance)
{
uniqeInstance = new Sample;
}
return uniqeInstance;
}
private:
Sample();
virtual ~Sample();
Sample(const Sample&);
Sample &operator=(const Sample &);
static Sample *uniqeInstance;
};
Example example;
Here example is an object on the stack.
Example* example=new Example();
This could be broken into:
Example* example;
....
example=new Example();
Here the first statement creates a variable example which is a "pointer to Example". When the constructor is called, memory is allocated for it on the heap (dynamic allocation). It is the programmer's responsibility to free this memory when it is no longer needed. (C++ does not have garbage collection like java).
In the first case you are creating the object on the heap using new.
In the second case you are creating the object on the stack, so it will be disposed of when going out of scope.
In C++ you'll need to delete objects on the heapexplicitly using delete when you don't Need them anymore.
To call a static method from a class, do
Singleton* singleton = Singleton::get_sample();
in your main-function or wherever.
So I have a class called List which stores a vector of pointers to classes of type Object. List has a function called add which initialises an Object class and adds it's pointer to the vector. I thought that once the add function ended that the Object class would be destroyed and accessing the pointer would cause an exception. When I wrote a test program to test this it turned out that the Object class was never destroyed.
Are classes initialised inside a function ever destroyed once the function ends?
When are classes automatically destroyed?
Depends how you're creating the object. If you are doing it like this:
void add() {
Object obj;
vec.push_back(&obj);
}
Then you are creating obj with automatic storage duration. That means it will be destroyed when the add function ends. The pointer you have pushed into the vector will no longer point to a valid Object, so definitely don't do this.
You may, however, be doing this:
void add() {
Object* obj = new Object();
vec.push_back(obj);
}
If you are, you are creating the Object with dynamic storage duration and it will not be destroyed at the end of the function. The pointer you push into the vector will remain valid. However, if you do this, you need to remember to delete the object at a later time. If you don't, you'll have a leak.
The best option is to avoid using pointers at all, if you can. Just make the vector a std::vector<Object> and copy objects into it:
void add() {
vec.push_back(Object());
}
Or in C++11:
void add() {
vec.emplace_back();
}
If you really need pointers, prefer smart pointers.
In C++, if you don't use any memory manager, smart pointers or some kind of "managed" environment, classes created using keyword new. To avoid misunderstanding could you please post constructor of Object and method List.Add?
So, when you are creating new object like:
Object* o = new Object();
you reserving space in the heap and store pointer to that space in pointer 'o'. If you never calling
delete o;
explicitly your object will never deleted.
Example:
Class *_obj1;
Class *_obj2;
void doThis(Class *obj) {}
void create() {
Class *obj1 = new Class();
Class obj2;
doThis(obj1);
doThis(&obj2);
_obj1 = obj1;
_obj2 = &obj2;
}
int main (int argc, const char * argv[]) {
create();
_obj1->doSomething();
_obj2->doSomething();
return 0;
}
This creates 2 objects, creates pointers to them, then main() calls a method on each. The Class object creates a char* and stores the C string "Hello!" in it; the ~Class() deallocator frees the memory. The doSomething() method prints out "buff: %s" using printf(). Simple enough. Now if we run it we get this:
Dealloc
Buff: Hello!
Buff: ¯ø_ˇ
Obviously the stack object does not work here - it's obvious that when the function exits the pointer _obj2 is pointing at a location in the stack. This is why I used heap objects in my previous question, which people told me was "stupid".
So, the first question is: if how can I convert the stack object (obj2) to a heap object so it's not deallocated after create() exits? I want a straight answer, not an arrogant "you're doing it wrong" as so many have done. Because in this case stack objects cannot work so heap objects seem to be the only way. EDIT: Also, converting back to a stack object would be useful as well.
The second question: the specific example of heap objects being "wrong" was creating a new vector<string>* using the new operator. If dynamically allocating STL objects is wrong, then what's the right way? Obviously if you create them as stack objects it fails because they're immediately deallocated, but I've been told (again, by a very high-ranking member) that dynamically allocating them can corrupt the heap. So what's the right way to do it?
So, the first question is: if how can I convert the stack object (obj2) to a heap object so it's not deallocated after create() exits? I want a straight answer,
The straight answer is: You can't "convert" an object between the stack and heap. You can create a copy of the object that lives in the other space, as others have pointed out, but that's it.
The second question: the specific example of heap objects being "wrong" was creating a new vector* using the new operator. If dynamically allocating STL objects is wrong, then what's the right way? Obviously if you create them as stack objects it fails because they're immediately deallocated, but I've been told (again, by a very high-ranking member) that dynamically allocating them can corrupt the heap.
Dynamically allocating STL objects will not on its own corrupt the heap. (No idea where you might have heard that.)
If you want to use a stack-allocated STL object outside of the function that you created it in, you can't, since the stack space in which the object resides is only valid inside the function that created it.
You can, however, return a copy of the object:
std::vector<char> SomeFunc()
{
std::vector<char> myvector;
// myvector.operations ...
return myvector;
}
As I said, though, this will return a copy of the object, not the original object itself -- that would be impossible, since the stack that contains the object is unwound after the function returns.
One other option is to have the caller pass in a reference / pointer to the object that your function manipulates, if this makes sense for your particular scenario:
void SomeFunc(std::vector<char>& destination)
{
// destination.operations ...
}
void AnotherFunc()
{
std::vector<char> myvector;
SomeFunc(myvector);
}
As you can see, you've still allocated everything on the stack, and you avoid the (sometimes consequential) overhead of relying on the copy-constructor to return a copy of the object.
So, the first question is: if how can I convert the stack object (obj2) to a heap object so it's not deallocated after create() exits?
This line:
_obj2 = &obj2;
Change to:
_obj2 = new Class(obj2); // Create an object on the heap invoking the copy constructor.
I want a straight answer, not an arrogant "you're doing it wrong" as so many have done.
Thats as straight an answer as you can get. Obviously you are new to C++, So I am sure this will nto work as intended because you have probably made a couple of mistakes in the defintion of the class "Class" (by the way terrible name).
Also, converting back to a stack object would be useful as well.
class obj3(*_obj2); // dereference the heap object pass it to the copy constructor.
The second question: the specific example of heap objects being "wrong" was creating a new vector<string>* using the new operator. If dynamically allocating STL objects is wrong, then what's the right way?
Why do you dynamically allocate the vector. Just create it locally.
std::vector<std::string> funct()
{
std::vector<std::string> vecString;
// fill your vector here.
return vecString; // Notice no dynamic allocation with new,
}
Using new/delete is using C++ like C. What you need to read up on is smart pointers. These are obejcts that control the lifespan of the object and automatically delete the object when they go out of scope.
std::auto_ptr<Class> x(new Class);
Here x is a smart pointer (of type auto_ptr) when it goes out of scope the object will be deleted. But you can return an auto_ptr to the calling function and it will be safely transfered out of the function. Its actually a lot more complicated than that and you need a book.
Obviously if you create them as stack objects it fails because they're immediately deallocated,
Its de'allocated when it goes out of scope.
but I've been told (again, by a very high-ranking member) that dynamically allocating them can corrupt the heap.
If you do it incorrectly. Which given your knowledge is very likely. But hard to verify since you have not provided the definition of Class.
So what's the right way to do it?
Learn why you should use stack objects
Learn what smart pointers are.
Learn how to use smart pointers to control lifespans of objects.
Learn the different types of smart pointers.
Look up what the separation of concerns is (you are not following this basic principle).
You have to either copy-construct a new heap object (Class * foo = new Class(obj2)) or assign the stack object to a heap object (*obj1 = obj2).
the only way is to copy object.
Change declaration to:
Class _obj2;
and assign:
_obj2 = obj2;
Taking the address of a stack variable won't magically transfer it into heap. You need to write a proper copy-constructor for your class and use _obj2 = new Class(obj2);.
As for STL containers, they allocate their data on the heap anyway, why would you want to allocate container itself on the heap? Put them in a scope that will keep them alive as long as you need them.
Your stack object is created inside the create function and is deallocated as soon you get out of scope of the function. The pointer is invalid.
You could change Class* obj2 to Class obj2 and the assign (which means copy) the object by obj2 = obj2;
I think you're really trying to ask "How can I return an object created inside my function?" There are several valid ways:
Allocate on the heap and return a pointer
Use an automatic variable and return its value, not a pointer (the compiler will copy it)
Let the caller provide storage, either by pointer or reference parameter, and build your object there.
Hi if I am creating something on the stack using new I declare it like:
object *myObject = new object(contr, params);
Is there a way to declare this such as:
object *myObject;
myObject = new object(constr, params);
Is this correct?
Yes, that is correct. But new does not create things on the stack, it creates them on the heap.
To create object on the stack you would do:
object myObject(constr, params);
There is no other way to create an object on the stack and once it is created on the stack you can't "recreate" it with the same name later in the same function.
As others have said, new will create *myObject on the heap. For completeness I'll point out that the pointer to the object, called myObject (note there is no *) does reside on the stack the way you declared it. Since stack variables go out of scope when you leave a function, you must delete the object before returning, or transfer the pointer to another variable with a longer lifetime. Neglecting to delete a heap object whose pointer is in a stack variable before returning from a function is sort of the canonical memory leak scenario (though far from the only one)
Yes that is correct but it won't allocate on the stack. Instead it will allocate on the heap. If you want to allocate on the stack, declare it this way
object myObject(contr,params);
If you want the object to be on the stack, you need to say
object myObject(contr, params);
This code:
object *myObject;
myObject = new object(constr, params);
...is legal & correct. But please please initialize myObject to something when you allocate it. Remember 'myObject' is itself not an instance of the 'object', but an instance of a pointer to an 'object'. So when you declare this pointer like this:
object *myObject;
...you are leaving it uninitialized. Instead, do this:
object *myObject = 0;
myObject = new object(constr, params);
...and when you delete it:
delete myObject;
myObject = 0;
People may debate that you should set it to NULL rather than 0, but both are fine as far as the language is concerned and this is mostly a matter of style and what your coworkers are used to.
I declared a private variable
vector<SomeClass> theVector;
someplace inside my SomeClass class.
Why can't I say: delete theVector inside my SomeClass destructor?
The compiler error says:
type `class Vector<SomeClass>' argument given to `delete', expected pointer
What expected pointer?
If new and delete go hand in hand.
To delete something you need to create it via new (which gives you a pointer). You can then delete the pointer. The way you are declaring the vector it is being created on the stack (not the heap) and will be deallocated when it goes out of scope.
int main()
{
vector<SomeClass> theVector;
vector<SomeClass>* ptrVctor = new vector<SomeClass>();
delete ptrVctor; // ptrVctor must be deleted manually
// theVector destroyed automatically here
}
In C++ (unlike Java), you can create objects either on the stack or the heap. An example of creating it on the stack is, as you have done:
vector<SomeClass> theVector;
This object goes out of scope when the stack frame disappears (normally when you return from the function that created the object.
Creating objects on the heap allows them to outlive the function that created them and you do that by performing:
vector<SomeClass> *theVectorPtr = new vector<SomeClass>();
You can then pass the theVectorPtr pointer back to the caller of the function (or store it globally, whatever you want).
In order to get rid of the object on the heap, you explicitly delete it:
delete theVectorPtr;
somewhere in your code.
Deleting an object on the heap ends the scope of that object, the same way returning from a function ends the scope of variables created on the stack.
If an object (rather than a value) is defined as a class member variable, then its storage is always tied to the object instance of that class.
Therefore, if the containing object is allocated on the stack, then that object and the field will die when the stack unrolls.
If the containing object is allocated on the heap, then the field object will die when the entire containing object dies with delete.
You will only be applying delete to a field if that is a pointer, since all that is stored with the containing object is the address of some other memory area, and you are deleting the materials in that area.
The memory for theVector is part of the memory allocated for the SomeClass object, so you can't delete it without deleting the entire SomeClass object. The memory for theVector will get automatically freed when the SomeClass object is destructed.
This is because theVector is not a pointer, which is what delete' expects. "Expected pointer" means the operand ofdelete' must be a pointer.
Compare this to
int theInt;
delete theInt;
It surely will generate an error similar to what you got.
To destroy all of the objects held in the vector, you would do the following:
theVector.resize(0);
This will happen automatically when the vector goes out of scope.
c++ gives you flexibility to create object in stack and heap.
When the object is created in heap through new operator as shown below it returns the pointer to the object in heap.
ClassA * pobj_class = new ClassA();
For object created in stack the constructor returns the object rather than pointer as shown below.
ClassA obj_class();
and stack object automatically destroyed when variable(obj_class) goes out of scope,but object created on heap lives for ever.So to destroy heap object c++ gives you delete operator that takes pointer as argument and destroys the object the pointer is pointing to.