Re-assinging an "auto_ptr" and Managing Memory - c++

I've a situation like this:
class MyClass
{
private:
std::auto_ptr<MyOtherClass> obj;
public:
MyClass()
{
obj = auto_ptr<MyOtherClass>(new MyOtherClass());
}
void reassignMyOtherClass()
{
// ... do funny stuff
MyOtherClass new_other_class = new MyOtherClass();
// Here, I want to:
// 1) Delete the pointer object inside 'obj'
// 2) Re-assign the pointer object of 'obj' to 'new_other_class'
// so that 'obj' now manages 'new_other_class' instead of the
// object that just got deleted manually
}
};
Is there a way to achieve this? Will the following code do what I want?
void MyClass::reassignMyOtherClass()
{
// ... still, do more funny stuff (flashback humor :-)
MyOtherClass new_other_class = new MyOtherClass();
obj.reset(new_other_class);
}
Will the memory of new_other_class be de-allocated in the default destructor of MyClass?

Yes it will.
You can use
obj.reset( new MyOtherClass() );
And I'd better use such constructor
MyClass():
obj( new MyOtherClass() )
{
}

From MSDN where describing reset
The member function evaluates the expression delete myptr, but only if the stored pointer value myptr changes as a result of function call. It then replaces the stored pointer with ptr.
It will do what you want.

Related

how delete class variable in struct?

InitMyObject(MyObject* ptr)
{
*ptr = MyObject();
}
struct Data
{
MyObject obj;
};
extern Data data;
// ...
InitMyObject(&data.obj);
delete &data.obj; // ? is this ok
How I can delete (call deconstructor) data.obj, I also try Data::obj as pointer (nullptr default) then pass the pointer but crashed on Init.
How I can delete (call deconstructor) data.obj
The destructor of data will destroy its subobjects. Since data has static storage, it is automatically destroyed at the end of the program.
delete &data.obj; // ? is this ok
No. You may only delete the result of a non-placement new expression. You may not delete a pointer to a member object.

What will be happen if you dynamically allocates memory for one object of the class as an argument?

class Example
{
private:
Example* pointer;
Example* pointer2;
public:
Example();
void setPointer2(Example* object);
};
Example::Example()
{
pointer = new Example();
}
void Example::setPointer2(Example* object)
{
this->pointer2 = object;
}
int main()
{
Example object;
object.setPointer2(new Example());
return 0;
}
Delete is not important. I just want to know what is the differences between this two object which is adresses holding by pointer and pointer2. Are they differently allocated? The actual question is, does it matter where to use the "new" operator?
A major problem you have in your code is infinite recursion! The constructor you have defined:
Example::Example()
{
pointer = new Example();
}
creates a new object of its own type. This will call the constructor (again), and that call will call the constructor (again and again...)
But, other than that issue, it doesn't really matter whether you create a new object by directly assigning its address to pointer or if you create the object elsewhere and then assign its address (later) to pointer2. Both will point to an object of the class.

error: 'new' cannot appear in a constant-expression

class A
{
int data;
public:
void display()
{
cout<<"Value is "<<data;
}
void set_data(int x)
{
this->data = x;
}
A object = new A();
};
When I run the above code, I get the error stating "new cannot appear in constant expression". Why is it so?
Operator new returns a pointer but A is not a pointer type. You want A*:
A* object = new A();
You also want to move the above statement outside your class body and place it into appropriate function such as main():
int main() {
A* p = new A();
// do work
delete p;
}
That being said you either don't need a pointer at all and you can simply use an object with automatic storage duration:
A object;
Or you want to consider using a smart pointer such as std::unique_ptr:
std::unique_ptr<A> p = std::make_unique<A>();
class A
{
public:
A * object = new A(); // In any case not: "A object = new A();"
};
Or:
class A
{
public:
A object;
};
-
See (let's assume, for a moment, that you don't get the error), in both cases, on the first construction of A object, it creates another A object as a data-member. This A data-member (let's call it object.object ) creates in its turn another A as its data-member (let's call it object.object.object), and so to infinity (or until no more memory). I mean, as a data-member, it can't be either as A* object = new A();, or as A object;
-
I am not sure what was your intention, but if you want to link one A-object to another A-object, the class should be something like that:
class A
{
public:
A * object = nullptr
};
you have to make object of class A into main().
void main(){
A object;
}
First of all, you cannot create an object in the class declaration. Class declaration is like a blue print of the class. It is to say these are the components of my class - variables and member functions. You cannot instantiate anything inside it as no memory is allocated during this stage.
Note that you can instantiate an object inside one of the member function including constructor. These are called during object creation when memory is allocated.
Even if you use this statement inside a constructor you will go into an infinite loop as the constructor calls its constructor and so on until you have memory overflow.
You can declare the object in main like this:
int main() {
A obj = new A();
//other operations
} //Object A is destroyed once you come out of main.
Or dynamically like this
int main() {
A* obj = new A(); //dynamic allocation
//other operations
delete obj; //explicitly destroy
}

Deleting instantiated objects outside of a function?

How do you delete an instantiated object inside a function then delete when another function is called?
For example:
int function_test(){
object* a = new object();
}
int function_test2(){
delete a;
}
Object a needs to be deleted when function_test2() is called. Function_test() creates and sets the value of object a.
In order to delete something, you need a pointer to something.
When you allocate an object in function function_test and want to delete it in function_test2 you need to take care of a way for function_test2 to get a hold of the pointer to the object you wish to delete.
There are multiple ways of doing that, but the most common one is for function_test to return the pointer to the caller, and then passing that pointer to function_test2:
object* function_test() {
object* a = new object();
...
return a;
}
void function_test2(object* a) {
...
delete a;
}
The caller would need to "transfer" the pointer, like this:
object obj = function_test();
...
function_test2(obj);
Other ways of transferring the pointer are using file-static pointers, using global pointers, and using instance variables when functions function_test and function_test2 are member functions of a class.
You can't transfer local variables between functions. If you like to do something like this, I suggest you return the pointer, so you can pass it to the next function.
object *function_test()
{
auto *o = new object{};
return o;
}
however, this has as disadvantage that you have to capture this variable everywhere where you call it and have to to do memory management. Most likely you just want to use something object oriented, similar to:
class ObjectOwner final
{
public:
int function_test(){
a = new object();
}
int function_test2(){
delete a;
}
private:
object *a{nullptr};
};
which can be used as:
ObjectOwner owner;
owner.function_test();
owner.function_test2();
Even better would be using a std::unique_ptr<object> so that when you forget to call the 2nd function, the memory is freed.
Finally, you can consider using a constructor/destructor.
class ObjectOwner final
{
public:
ObjectOwner()
: a(std::make_unique<object>())
{
}
~ObjectOwner() = default;
void func() { /*Do something with a*/ }
private:
std::unique_ptr<object> a{};
};
Allowing you to write:
ObjectOwner owner{};
owner.func();

Class constructors in C++

I'm a beginner to c++ so there are a lot of things quite not clear in my mind.
I have this code I need to write and in a class I make a constructor.
However, I don't need any parameters because I read from a file-stream inside the constructor. So my questions are:
1.Can I make a constructor like this:
class myClass {
private:
string title;
string organizer;
public:
myClass() {
title = stringRead();
organizer = stringRead();
}
}
where stringRead() is a function I have written to read from my file??
2.How do I call it afterwards when I need it? I know that the default constructror is being called like that:
myClass A;
A = myClass();
Is it the same?
3.If I have a pointer, how do I call the constructor again? This doesn't seem like it should be right...
myClass *B;
B = myClass();
Thanks in advance! =D
1) This constructor will work but you should favor using an initialization list (assuming stringRead() isn't a member function of myClass
class myClass {
private:
string title;
string organizer;
public:
myClass()
: title(stringRead()),
organizer(stringRead())
{ }
};
2) myClass A; is what you should be doing. You could alternatively have auto A = myClass(); which, after optimizations, will be the same thing. Without optimizations a temporary will be constructed, and then A will be move constructed from it, so this won't work with unmovable objects (your object is movable)
3) If you want to use a raw pointer then you would use
myClass *ptr = new myClass;
// bunch of code
delete ptr;
However, you'd be better using a smart pointer to control its lifetime. This way you won't need to manually delete
std::unique_ptr<myClass> ptr(new myClass);
or make_unique in c++14
auto ptr = std::make_unique<myClass>();
And of course use a shared_ptr if you have shared ownership
I think it's OK to assign the value returned by a function to a member of a class.
You can initialize it as you suggested (with myClass A;)
When you use pointers, you need myClass *k=new myClass();. You should remember to delete the object you created with delete k;.
Your constructor is fine, so long as the functions used within it are globals or static functions of this or another class.
myClass A; will invoke the constructor you have written.
To use a pointer, you need B = new myClass(). That will also call the same constructor. Don't forget to delete B at some point else you'll leak memory.
Do bear in mind that if an exception is thrown in a constructor then the destructor is not called.
Yes, you can, but it might not be the best approach. Reading from input can fail, failure in a constructor is often a non-recoverable event you'll want to handle. A good approach is reading the values outside the costructor, handling errors and calling the constructor only when you have "everything ready". Like this:
class myClass {
private:
string _title;
string _organizer;
public:
myClass(const string &title, const string &organizer) {
_title = title;
_organizer = organizer;
}
or, by using a more idiomatic C++ initializer list:
class myClass {
private:
string _title;
string _organizer;
public:
myClass(const string &title, const string &organizer):
_title(title), _organizer(organizer) {}
}
and then, somewhere else:
string title = stringRead();
string organizer = stringRead();
myClass A(title, organizer);
No, in this snippet:
myClass A;
A = myClass();
two different things happen: at line 1 the default constructor is called; at line 2, a temporary object is constructed (again, by calling the default constructor) and then assigned to A using the (rval for C++11) copy operator. This expression:
myClass A;
calls the default constructor. If you have parameters:
myClass A(title, organizer);
Nope, this does not even work. A pointer is not an object, you have to allocate the object. At that point, you can get a pointer to it:
myClass A;
myClass *B = &A;
you could also resort to dynamic allocation:
myClass *B = new myClass;
in this case, either remember to call delete B somewhere else or wrap B in a smart pointer:
std::unique_ptr<myClass> B(new myClass());