What is the preferred way to instantiate in C++? - c++

I am still new to C++. I have found that you can instantiate an instance in C++ with two different ways:
// First way
Foo foo;
foo.do_something();
// Second way
Baz *baz = new Baz();
baz->do_something();
And with both I don't see big difference and can access the attributes. Which is the preferred way in C++? Or if the question is not relevant, when do we use which and what is the difference between the two?
Thank you for your help.

The question is not relevant: there's no preferred way, those just do different things.
C++ both has value and reference semantics. When a function asks for a value, it means you'll pass it a copy of your whole object. When it asks for a reference (or a pointer), you'll only pass it the memory address of that object. Both semantics are convertible, that is, if you get a value, you can get a reference or a pointer to it and then use it, and when you get a reference you can get its value and use it. Take this example:
void foo(int bar) { bar = 4; }
void foo(int* bar) { *bar = 4; }
void test()
{
int someNumber = 3;
foo(someNumber); // calls foo(int)
std::cout << someNumber << std::endl;
// printed 3: someNumber was not modified because of value semantics,
// as we passed a copy of someNumber to foo, changes were not repercuted
// to our local version
foo(&someNumber); // calls foo(int*)
std::cout << someNumber << std::endl;
// printed 4: someNumber was modified, because passing a pointer lets people
// change the pointed value
}
It is a very, very common thing to create a reference to a value (i.e. get the pointer of a value), because references are very useful, especially for complex types, where passing a reference notably avoids a possibly costly copy operation.
Now, the instantiation way you'll use depends on what you want to achieve. The first way you've shown uses automatic storage; the second uses the heap.
The main difference is that objects on automatic storage are destroyed with the scope in which they existed (a scope being roughly defined as a pair of matching curly braces). This means that you must not ever return a reference to an object allocated on automatic storage from a regular function, because by the time your function returns, the object will have been destroyed and its memory space may be reused for anything at any later point by your program. (There are also performance benefits for objects allocated on automatic storage because your OS doesn't have to look up a place where it might put your new object.)
Objects on the heap, on the other hand, continue to exist until they are explicitly deleted by a delete statement. There is an OS- and platform-dependant performance overhead to this, since your OS needs to look up your program's memory to find a large enough unoccupied place to create your object at. Since C++ is not garbage-collected, you must instruct your program when it is the time to delete an object on the heap. Failure to do so leads to leaks: objects on the heap that are no longer referenced by any variable, but were not explicitly deleted and therefore will exist until your program exits.
So it's a matter of tradeoff. Either you accept that your values can't outlive your functions, or you accept that you must explicitly delete it yourself at some point. Other than that, both ways of allocating objects are valid and work as expected.
For further reference, automatic storage means that the object is allocated wherever its parent scope was. For instance, if you have a class Foo that contains a std::string, the std::string will exist wherever you allocate your Foo object.
class Foo
{
public:
// in this context, automatic storage refers to wherever Foo will be allocated
std::string a;
};
int foo()
{
// in this context, automatic storage refers to your program's stack
Foo bar; // 'bar' is on the stack, so 'a' is on the stack
Foo* baz = new Foo; // 'baz' is on the heap, so 'a' is on the heap too
// but still, in both cases 'a' will be deleted once the holding object
// is destroyed
}
As stated above, you cannot directly leak objects that reside on automatic storage, but you cannot use them once the scope in which they were created is destroyed. For instance:
int* foo()
{
int a; // cannot be leaked: automatically managed by the function scope
return &a; // BAD: a doesn't exist anymore
}
int* foo()
{
int* a = new int; // can be leaked
return a; // NOT AS BAD: now the pointer points to somewhere valid,
// but you eventually need to call `delete a` to release the memory
}

The first way -- "allocating on the stack" -- is generally faster and preferred much of the time. The constructed object is destroyed when the function returns. This is both a blessing -- no memory leaks! -- and a curse, because you can't create an object that lives for a longer time.
The second way -- "allocating on the heap" is slower, and you have to manually delete the objects at some point. But it has the advantage that the objects can live on until you delete them.

The first way allocates the object on the stack (though the class itself may have heap-allocated members). The second way allocates the object on the heap, and must be explicitly delete'd later.
It's not like in languages like Java or C# where objects are always heap-allocated.

They do very different things. The first one allocates an object on the stack, the 2nd on the heap. The stack allocation only lasts for the lifetime of the declaring method; the heap allocation lasts until you delete the object.
The second way is the only way to dynamically allocate objects, but comes with the added complexity that you must remember to return that memory to the operating system (via delete/delete[]) when you are done with it.

The first way will create the object on the stack, and the object will go away when you return from the function it was created in.
The second way will create the object on the heap, and the object will stick around until you call delete foo;.
If the object is just a temporary variable, the first way is better. If it's more permanent data, the second way is better - just remember to call delete when you're finally done with it so you don't build up cruft on your heap.
Hope this helps!

Related

C++ member array destructor [duplicate]

I have a simple C++ code, but I don't know how to use the destructor:
class date {
public:
int day;
date(int m)
{
day =m;
}
~date(){
cout << "I wish you have entered the year \n" << day;
}
};
int main()
{
date ob2(12);
ob2.~date();
cout << ob2.day;
return 0;
}
The question that I have is, what should I write in my destructor code, that after calling the destructor, it will delete the day variable?
Rarely do you ever need to call the destructor explicitly. Instead, the destructor is called when an object is destroyed.
For an object like ob2 that is a local variable, it is destroyed when it goes out of scope:
int main()
{
date ob2(12);
} // ob2.~date() is called here, automatically!
If you dynamically allocate an object using new, its destructor is called when the object is destroyed using delete. If you have a static object, its destructor is called when the program terminates (if the program terminates normally).
Unless you create something dynamically using new, you don't need to do anything explicit to clean it up (so, for example, when ob2 is destroyed, all of its member variables, including day, are destroyed). If you create something dynamically, you need to ensure it gets destroyed when you are done with it; the best practice is to use what is called a "smart pointer" to ensure this cleanup is handled automatically.
You do not need to call the destructor explicitly. This is done automatically at the end of the scope of the object ob2, i.e. at the end of the main function.
Furthermore, since the object has automatic storage, its storage doesn’t have to be deleted. This, too, is done automatically at the end of the function.
Calling destructors manually is almost never needed (only in low-level library code) and deleting memory manually is only needed (and only a valid operation) when the memory was previously acquired using new (when you’re working with pointers).
Since manual memory management is prone to leaks, modern C++ code tries not to use new and delete explicitly at all. When it’s really necessary to use new, then a so-called “smart pointer” is used instead of a regular pointer.
You should not call your destructor explicitly.
When you create your object on the stack (like you did) all you need is:
int main()
{
date ob2(12);
// ob2.day holds 12
return 0; // ob2's destructor will get called here, after which it's memory is freed
}
When you create your object on the heap, you kinda need to delete your class before its destructor is called and memory is freed:
int main()
{
date* ob2 = new date(12);
// ob2->day holds 12
delete ob2; // ob2's destructor will get called here, after which it's memory is freed
return 0; // ob2 is invalid at this point.
}
(Failing to call delete on this last example will result in memory loss.)
Both ways have their advantages and disadvantages. The stack way is VERY fast with allocating the memory the object will occupy and you do not need to explicitly delete it, but the stack has limited space and you cannot move those objects around easily, fast and cleanly.
The heap is the preferred way of doing it, but when it comes to performance it is slow to allocate and you have to deal with pointers. But you have much more flexibility with what you do with your object, it's way faster to work with pointers further and you have more control over the object's lifetime.
Only in very specific circumstances you need to call the destructor directly. By default the destructor will be called by the system when you create a variable of automatic storage and it falls out of scope or when a an object dynamically allocated with new is destroyed with delete.
struct test {
test( int value ) : value( value ) {}
~test() { std::cout << "~test: " << value << std::endl; }
int value;
};
int main()
{
test t(1);
test *d = new t(2);
delete d; // prints: ~test: 2
} // prints: ~test: 1 (t falls out of scope)
For completeness, (this should not be used in general) the syntax to call the destructor is similar to a method. After the destructor is run, the memory is no longer an object of that type (should be handled as raw memory):
int main()
{
test t( 1 );
t.~test(); // prints: ~test: 1
// after this instruction 't' is no longer a 'test' object
new (&t) test(2); // recreate a new test object in place
} // test falls out of scope, prints: ~test: 2
Note: after calling the destructor on t, that memory location is no longer a test, that is the reason for recreation of the object by means of the placement new.
In this case your destructor does not need to delete the day variable.
You only need to call delete on memory that you have allocated with new.
Here's how your code would look if you were using new and delete to trigger invoking the destructor
class date {
public: int* day;
date(int m) {
day = new int;
*day = m;
}
~date(){
delete day;
cout << "now the destructor get's called explicitly";
}
};
int main() {
date *ob2 = new date(12);
delete ob2;
return 0;
}
Even though the destructor seems like something you need to call to get rid of or "destroy" your object when you are done using it, you aren't supposed to use it that way.
The destructor is something that is automatically called when your object goes out of scope, that is, when the computer leaves the "curly braces" that you instantiated your object in. In this case, when you leave main(). You don't want to call it yourself.
You may be confused by undefined behavior here. The C++ standard has no rules as to what happens if you use an object after its destructor has been run, as that's undefined behavior, and therefore the implementation can do anything it likes. Typically, compiler designers don't do anything special for undefined behavior, and so what happens is an artifact of what other design decisions were made. (This can cause really weird results sometimes.)
Therefore, once you've run the destructor, the compiler has no further obligation regarding that object. If you don't refer to it again, it doesn't matter. If you do refer to it, that's undefined behavior, and from the Standard's point of view the behavior doesn't matter, and since the Standard says nothing most compiler designers will not worry about what the program does.
In this case, the easiest thing to do is to leave the object untouched, since it isn't holding on to resources, and its storage was allocated as part of starting up the function and will not be reclaimed until the function exits. Therefore, the value of the data member will remain the same. The natural thing for the compiler to do when it reads ob2.day is to access the memory location.
Like any other example of undefined behavior, the results could change under any change in circumstances, but in this case they probably won't. It would be nice if compilers would catch more cases of undefined behavior and issue diagnostics, but it isn't possible for compilers to detect all undefined behavior (some occurs at runtime) and often they don't check for behavior they don't think likely.

Where is this memory allocation allocated?

Here's the line of code:
A a = static_cast<A>(*(new A)); // ?
It compiles fine on 64bit clang at least.
But where is the memory actually allocated and what happens to variable a?
Besides there's no static cast needed, the memory allocated with new A simply leaks. You have lost access to that pointer and can never delete it properly anymore.
But where is the memory actually allocated and what happens to variable a?
Variable a is destroyed as soon it leaves scope as usual.
A a = static_cast<A>(*(new A)); // ?
This does the following.
(new A) // allocate a new A on the heap
*(new A) // the type is now A instead of *A
static_cast<A>(*(new A)) // makes it into an type A from type A in an potentially unsafe way (here it is a no-op as they are the same type)
A a = static_cast<A>(*(new A)); // copies the (default) value of A to a
; // leaks the allocted A as the last reference to it disappear.
I'm going to answer this question on the assumption that this line of code appears inside a function. If it appears elsewhere, the bit about the "stack" is inaccurate but everything else is still accurate.
This line of code compiles to four operations, which we can write as their own lines of C++ to make things clearer. It makes two allocations, in two different places, and one of them is "leaked".
A a;
{
A *temp = new A;
a = *temp;
}
The first operation allocates space for an object of type A on the "stack", and default-initializes it. This object is accessible through the variable a. It will be automatically destructed and deallocated no later than when the function returns; depending on surrounding context, this might happen earlier, but in no case while the variable a is in scope.
The second operation allocates space for another object of type A, but on the "heap" instead of the "stack". This object is also default-initialized. The new operator returns a pointer to this object, which the compiler stores in an temporary variable. (I gave that variable the name temp because I had to give it some name; in your original code the temporary is not accessible by any means.) This object will only ever be deallocated if, at some point in the future, the pointer returned by new is used in a delete operation.
The third operation, finally, copies the contents of the object on the heap, pointed to by temp, into the object on the stack, accessible via the variable a. (Note: the static_cast<A>(...) that you had written here has no effect whatsoever, because *temp already has the type A. Therefore, I took it out.)
Finally, the temporary variable holding the pointer to the object on the heap is discarded. The object on the heap is not deallocated when this happens; in fact, it becomes impossible for anything ever to deallocate it. That object is said to have leaked.
You probably wanted to write either
A a;
which allocates an object on the stack and does nothing else, or
// note: C++11 only; C++03 equivalent is std::shared_ptr<A> a(new A());
auto a = std::make_shared<A>();
which allocates an object on the heap and arranges to reference-count it, so that it probably won't leak. (There are a few other things you might have meant, but those are the most likely.)
For a simple definition of A, it is equivalent to:
A a(*new(A));
An A is dynamically allocated on the heap, a is copy constructed on the stack, and the dynamic allocation is leaked.
For a trivial definition of A the overall effect might as well be:
new A;
A a;
this copy implements the leak without the wasteful copy operation or the messy, redundant cast :)

How to Convert beween Stack and Heap Objects

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.

Storing a pointer to an object created in a method

Using C++:
I currently have a method in which if an event occurs an object is created, and a pointer to that object is stored in a vector of pointers to objects of that class. However, since objects are destroyed once the local scope ends, does this mean that the pointer I stored to the object in the vector is now null or undefined? If so, are there any general ways to get around this - I'm assuming the best way would be to allocate on the heap.
I ask this because when I try to access the vector and do operations on the contents I am getting odd behavior, and I'm not sure if this could be the cause or if it's something totally unrelated.
It depends on how you allocate the object. If you allocate the object as an auto variable, (i.e. on the stack), then any pointer to that object will become invalid once the object goes out of scope, and so dereferencing the pointer will lead to undefined behavior.
For example:
Object* pointer;
{
Object myobject;
pointer = &myobject;
}
pointer->doSomething(); // <--- INVALID! myobject is now out of scope
If, however, you allocate the object on the Heap, using the new operator, then the object will remain valid even after you exit the local scope. However, remember that there is no automatic garbage collection in C++, and so you must remember to delete the object or you will have a memory leak.
So if I understand correctly you have described the following scenario:
class MyClass
{
public:
int a;
SomeOtherClass b;
};
void Test()
{
std::vector<MyClass*> v;
for (int i=0; i < 10; ++i)
{
MyClass b;
v.push_back(&b);
}
// now v holds 10 items pointers to strange and scary places.
}
This is definitely bad.
There are two primary alternatives:
allocate the objects on the heap using new.
make the vector hold instances of MyClass (i.e. std::vector<MyClass>)
I generally prefer the second option when possible. This is because I don't have to worry about manually deallocating memory, the vector does it for me. It is also often more efficient. The only problem, is that I would have to be sure to create a copy constructor for MyClass. That means a constructor of the form MyClass(const MyClass& other) { ... }.
If you store a pointer to an object, and that object is destroyed (e.g. goes out of scope), that pointer will not be null, but if you try to use it you will get undefined behavior. So if one of the pointers in your vector points to a stack-allocated object, and that object goes out of scope, that pointer will become impossible to use safely. In particular, there's no way to tell whether a pointer points to a valid object or not; you just have to write your program in such a way that pointers never ever ever point to destroyed objects.
To get around this, you can use new to allocate space for your object on the heap. Then it won't be destroyed until you delete it. However, this takes a little care to get right as you have to make sure that your object isn't destroyed too early (leaving another 'dangling pointer' problem like the one you have now) or too late (creating a memory leak).
To get around that, the common approach in C++ is to use what's called (with varying degrees of accuracy) a smart pointer. If you're new to C++ you probably shouldn't worry about these yet, but if you're feeling ambitious (or frustrated with memory corruption bugs), check out shared_ptr from the Boost library.
If you have a local variable, such as an int counter, then it will be out of scope when you exit the function, but, unless you have a C++ with a garbage collector, then your pointer will be in scope, as you have some global vector that points to your object, as long as you did a new for the pointer.
I haven't seen a situation where I have done new and my memory was freed without me doing anything.
To check (in no particular order):
Did you hit an exception during construction of member objects whose pointers you store?
Do you have a null-pointer in the container that you dereference?
Are you using the vector object after it goes out of scope? (Looks unlikely, but I still have to ask.)
Are you cleaning up properly?
Here's a sample to help you along:
void SomeClass::Erase(std::vector<YourType*> &a)
{
for( size_t i = 0; i < a.size(); i++ ) delete a[i];
a.clear();
}

C++ - What does "Stack automatic" mean?

In my browsings amongst the Internet, I came across this post, which includes this
"(Well written) C++ goes to great
lengths to make stack automatic
objects work "just like" primitives,
as reflected in Stroustrup's advice to
"do as the ints do". This requires a
much greater adherence to the
principles of Object Oriented
development: your class isn't right
until it "works like" an int,
following the "Rule of Three" that
guarantees it can (just like an int)
be created, copied, and correctly
destroyed as a stack automatic."
I've done a little C, and C++ code, but just in passing, never anything serious, but I'm just curious, what it means exactly?
Can someone give an example?
Stack objects are handled automatically by the compiler.
When the scope is left, it is deleted.
{
obj a;
} // a is destroyed here
When you do the same with a 'newed' object you get a memory leak :
{
obj* b = new obj;
}
b is not destroyed, so we lost the ability to reclaim the memory b owns. And maybe worse, the object cannot clean itself up.
In C the following is common :
{
FILE* pF = fopen( ... );
// ... do sth with pF
fclose( pF );
}
In C++ we write this :
{
std::fstream f( ... );
// do sth with f
} // here f gets auto magically destroyed and the destructor frees the file
When we forget to call fclose in the C sample the file is not closed and may not be used by other programs. (e.g. it cannot be deleted).
Another example, demonstrating the object string, which can be constructed, assigned to and which is destroyed on exiting the scope.
{
string v( "bob" );
string k;
v = k
// v now contains "bob"
} // v + k are destroyed here, and any memory used by v + k is freed
In addition to the other answers:
The C++ language actually has the auto keyword to explicitly declare the storage class of an object. Of course, it's completely needless because this is the implied storage class for local variables and cannot be used anywhere. The opposite of auto is static (both locally and globall).
The following two declarations are equivalent:
int main() {
int a;
auto int b;
}
Because the keyword is utterly useless, it will actually be recycled in the next C++ standard (“C++0x”) and gets a new meaning, namely, it lets the compiler infer the variable type from its initialization (like var in C#):
auto a = std::max(1.0, 4.0); // `a` now has type double.
Variables in C++ can either be declared on the stack or the heap. When you declare a variable in C++, it automatically goes onto the stack, unless you explicitly use the new operator (it goes onto the heap).
MyObject x = MyObject(params); // onto the stack
MyObject * y = new MyObject(params); // onto the heap
This makes a big difference in the way the memory is managed. When a variable is declared on the stack, it will be deallocated when it goes out of scope. A variable on the heap will not be destroyed until delete is explicitly called on the object.
Stack automatic are variables which are allocated on the stack of the current method. The idea behind designing a class which can acts as Stack automatic is that it should be possible to fully initialize it with one call and destroy it with another. It is essential that the destructor frees all resources allocated by the object and its constructor returns an object which has been fully initialized and ready for use. Similarly for the copy operation - the class should be able to be easily made copies, which are fully functional and independent.
The usage of such class should be similar to how primitive int, float, etc. are used. You define them (eventually give them some initial value) and then pass them around and in the end leave the compiler to the cleaning.
Correct me if i'm wrong, but i think that copy operation is not mandatory to take full advantage of automatic stack cleaning.
For example consider a classic MutexGuard object, it doesn't need a copy operation to be useful as stack automatic, or does it ?