polymophism of pointers - c++

I am using a boost::ptr_vector, but I believe this applies to a standard std::vector as well. I am trying to place pointers to objects polymophically into a boost::ptr_vector the hierarchy is that I have an Entity that inherits from Object being created with the line
Object * newObject = new Entity(param1, param2); // then I attempt to add it to the ptr_vector
but if I break the program (Visual Studio 2010) to look at what is being held the pointer is never redirected from garbage, and garbage is being held. I step through the code, and it does enter the parameterized constructor, and follows the correct logical steps with it.
I am uncertain what is going wrong. do I need to have specific member functions in the parent, or the child in order for this polymorphic behavior to work (currently all children have parameterized constructors unique to their type, and destructors along with polymorphic interaction methods). must I have assignment operators, or should I have a constructor in the Object class.
It seems to be that the call to operator new is not resolving to an object, but resolving to something else, but VS2010 is not throwing an error.
Edit: explanation of what should be happening.
stepping through a 2D std::vector(rectangular/non-jagged)
using case/switch to determine object to be generated, and added to structure
pointer to Object is created, and assigned to new // I think this is where the problem is happening
then the reference of that pointer is pushed onto a manager-member boost::ptr_vector
in Visual Studio 2010 I put a break at the line to create the pointer, and assign new (polymorphic), and one on the line for the push_back() to the boost::ptr_vector watching the pointer. The temp pointer value is created, and stepping into the constructor it follows all logical steps for that constructor, and when the constructor finishes, and the stack returns to the line that called the constructor the pointer is still the same value (I think this is acceptable), but when I look at the object that it points to all the values show up as question marks (including the statically composed member objects). then when the push back triggers, and enters boost-header the x value show the same information.
it almost seems like the pointer is being made, and the datams of the object are created, but once the constructor is finished it doesn't actually assign the values to the parent class object which should be considerably simple with regards to polymophic behavior.
example headers of concern (the real headers do have member variables, and their implementations are in a separate cpp file):
class Object{
public :
virtual void interact(int action, Object& source){}
virtual void updateObject(float duration){}
virtual ~Object(){}
bool operator==(const Object& _other)const;
bool operator!=(const Object& _other)const;
};
class Entity : public Object{
public:
Entity(Vector3 location, Type thisType, SpecialType difficulty=noSpecial);
~Entity();
void interact(int action, Object& source);
void updateObject(float duration);
};
Edit: changing context to better target problem at hand, and receive a solution

The pointer value only changes after the constructor has finished, it's not a problem. It's logical because first a temporary pointer is acted upon and only the it is assigned to your pointer.

After
Object * newObject = new Entity(param1, param2);
you will have newObject pointing to the freshly created object. While the constructor is
running, newObject is still not assigned. If you have afterwards e.g.
vec.push_back(newObject);
you can step into the push_back method and see the argument is an Object having
a virtual table referencing to Entity methods. (You have a virtual destructor at least,
right?)

Based on what you've posted, it's difficult (if even possible) to be sure of the problem, not to mention how it's coming about/how to fix it.
Perhaps it's better to start from something that actually works, and add the functionality you need, or at least get some idea of places you're deviating from what's expected/what works. So, here's a small sample of creating objects dynamically, putting them into a ptr_vector, using a virtual function in each to verify that what's in the container is what's expected, and then letting the container go out of scope (and in the process, destroying the objects referred to by the pointers it contains).
#include "boost/ptr_container/ptr_vector.hpp"
#include <iostream>
#include <string>
#include <sstream>
class Object {
std::string name;
public:
Object(std::string const &n) : name(n) {}
virtual std::ostream &write(std::ostream &os) const {
return os << name;
}
virtual ~Object() { std::cout << "Object being destroyed\n"; }
};
class Entity : public Object {
int value;
public:
Entity(int v, std::string name) : Object(name), value(v) {}
std::ostream &write(std::ostream &os) const {
return os << "Entity: " << value;
}
~Entity() { std::cout << "Entity being destroyed\n"; }
};
int main() {
boost::ptr_vector<Object> objects;
for (int i=0; i<10; i++) {
std::stringstream name;
name << "object: " << i;
if (i & 1)
objects.push_back(new Object(name.str()));
else
objects.push_back(new Entity(i, name.str()));
}
boost::ptr_vector<Object>::iterator pos;
for (pos = objects.begin(); pos != objects.end(); pos++) {
pos->write(std::cout);
std::cout << "\n";
}
return 0;
}
At least for me, the output looks like this:
Entity: 0
object: 1
Entity: 2
object: 3
Entity: 4
object: 5
Entity: 6
object: 7
Entity: 8
object: 9
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
For what it's worth, note the destructors -- when an Object is destroyed, only the base dtor is invoked, but when an Entity is destroyed, first the derived dtor is invoked, then the base dtor is invoked (so we see both 'Entity being destroyed' and 'Object being destroyed").

Related

When is the destructor of an object that is being moved to called in C++?

I have some class A, which I can either construct using nothing, or an std::function. On destruction that given function should be called (in case there is one). My problem is that the object gets destroyed right after it is created and returned by my getSomeA() function which calls the std::function before it is supposed to be called. The function passed to the constructor should only be called once. Some example code:
#include <iostream>
#include <functional>
static void testFunction(const std::string& msg)
{
std::cout << "TestFunction: " << msg << "\n";
}
class A {
public:
A(void) = default;
A(const std::function<void()>& onDestroy) :
onDestroy(onDestroy)
{ }
~A(void)
{
if (onDestroy) onDestroy();
else std::cout << "in dtor but no onDestroy was set\n";
}
private:
std::function<void()> onDestroy;
};
A getSomeA(void)
{
return A(std::bind(testFunction, "the A that was created inside getSomeA"));
}
int main(void)
{
A b1;
std::cout << "After creating b1\n";
b1 = getSomeA();
std::cout << "After reassigning b1\n";
std::cout << "Here the program works with b1...\n";
}
The program outputs
After creating b1
TestFunction: the A that was created inside getSomeA
After reassigning b1
Here the program works with b1...
TestFunction: the A that was created inside getSomeA
So the function is called before it is supposed to be called (at the end of int main()).
After adding a move constructor and assignment operator everything works as expected:
A(A&& other) :
onDestroy(std::exchange(other.onDestroy, nullptr))
{ }
A& operator=(A&& other)
{
onDestroy = std::exchange(other.onDestroy, nullptr);
return *this;
}
And the program outputs
After creating b1
in dtor but no onDestroy was set
After reassigning b1
Here the program works with b1...
TestFunction: the A that was created inside getSomeA
The actual question: Where is the object destroyed for the first time so that testFunction is called? In getSomeA() or in the main function before the assignment but after the object was created in getSomeA()?
All the edits: I tried to bring down my question for one hour but since I have no idea about move/copy semantics in C++ that was pretty hard for me.
In the first version the object gets destroyed for the first time as part of returning the object constructed in getSomeA. Its return statement effectively constructs a temporary object, which then gets assigned to main's b1. If you ignore the process of returning from a function, the sequence of events is:
A <temporary object>(std::bind( ... )
b1=<temporary object>
<temporary object gets destroyed>
At this point the bound function gets called, as a result of the temporary object gets destroyed. The temporary object is a fully tricked out object, with all the rights and privileged granted thereof. Including a destructor.
But wait, there's more! b1 is a perfect bit-by-bit copy of the original object, with the bound function, before it got destroyed. So when b1 gets destroyed, the function gets called again.
This is the indirect consequence of the Rule Of Three. When an object owns a resource, and must maintain an exclusive ownership of the resource you will need to provide a copy and/or move constructor and and assignment operator to spell out exactly what should happen in that situation.
P.S. these rules change slightly with C++17's guaranteed copy elision, but the underlying concept is still the same.

Copy Constructor for not dynamic allocation

According to definition : When an object of this class is copied, the pointer member is copied, but not the pointed buffer, resulting in two objects pointing to the same so we use copy constructor. But in following class there is no copy constructor but it Works! why? Why i dont need to deep copying?
class Human
{
private:
int* aValue;
public:
Human(int* param)
{
aValue=param;
}
void ShowInfos()
{
cout<<"Human's info:"<<*aValue<<endl;
}
};
void JustAFunction(Human m)
{
m.ShowInfos();
}
int main()
{
int age = 10;
Human aHuman(&age);
aHuman.ShowInfos();
JustAFunction(aHuman);
return 0;
}
output:
Human's info : 10
Human's info : 10
A copy constructor is useful when your class owns resources. In your case, it doesn't - it neither creates nor deletes aValue itself.
If you did do that though, say:
Human()
{
aValue=new int;
}
and properly cleaned up the memory:
~Human()
{
delete aValue;
}
then you'd run into issues, because Human a; and Human b(a); would have the members aValue point to the same location, and the when they go out of scope, the same memory is released, resulting in a double delete.
As has already been mentioned, the reason it works for you is that it's actually fine to have multiple pointers pointing to the same object - that's kind of the point, share data without copying it.
the issues arrive if the object pointed to has it's lifetime managed by the wrapping class, ie: it is created and destroyed within methods implemented by the class - typically the class's constructor and destructor. In that case a deep copy would be necessary in the copy constructor.
In your (admittedly contrived) example where the int has a longer lifetime that the object carrying the pointer you should examine using a reference as a member, initialised in an initialiser list. This removes the possibility of forgetting yourself and deleting the object from within the class.
class Human
{
private:
int& aRef;
public:
Human(int& param)
: aRef(param)
{
}
};
You should also consider whether the pointer or reference should be to a const object:
class Human
{
private:
const int& aRef;
public:
Human(const int& param)
: aRef(param)
{
}
};
This works because the pointer in the class points to the stack variable age.
You haven't written a destructor for your class Human, so doesn't try to do a double delete when the Human is copied in JustAFunction
If you used it differently, for example sending a newed int into the class you would have a memory leak instead.
Human human(new int);
If you copy that, you have two pointers pointing to the same memory, which in itself isn't a problem, but makes it hard to decide who is in charge of releasing that memory.

Field variable deleted before actual destructor called?

What would make a field variable become obsolete before entering the destructor upon deletion of the object?
I was a looking for an answer for this problem I'm having on this site and came across this:
Lifetime of object is over before destructor is called?
Something doesn't add up at all: if I've declared a pointer to SomeClass inside another WrapperClass, when I construct the WrapperClass I need to create a new SomeClass and delete it on destruction of the wrapper.
That makes sense and has worked so far.
The pointer is still valid and correct well into the destructor otherwise obviously I wouldn't be able to delete it.
Now my problem is that my field members (both an int and a pointer to a SomeClass array) of WrapperClass are garbage when I call the destructor. I've checked the wrapper object just after construction and the data is fine. The wrapper is actually a pointer in another Main class and the problem occurs when I destruct that Main (which destructs the wrapper) but works fine if I just delete the wrapper from another method in Main.
My paranoia led me to the above mentioned answer and now I'm totally confused.
Anybody care to shed some light on what's really going on here?
EDIT:
Node is the SomeClass.
class WrapperException{};
class Wrapper {
private:
struct Node { /*....*/ };
int numNodes;
Node** nodes;
public:
Wrapper() : numNodes(0) { nodes = new Node*[SIZE]; }
Wrapper(const Wrapper& other) { throw WrapperException(); }
Wrapper& operator=(const Wrapper& other) { throw WrapperException(); }
~Wrapper() { //calling delete Main gets me here with garbage for numNodes and nodes
for(int i = 0; i < numNodes; i++)
delete nodes[i];
delete nodes;
}
};
class MainException{};
class Main {
public:
Main() { wrapper = new Wrapper(); }
Main(const Main& other) { throw MainException(); }
Main& operator=(const Main& other) { throw MainException(); }
~Main() { delete wrapper; }
private:
Wrapper* wrapper;
};
You need to use the Standard library to implement this behaviour.
class Wrapper {
private:
struct Node { /*....*/ };
int numNodes;
std::vector<std::unique_ptr<Node>> nodes;
public:
Wrapper() : numNodes(0) { nodes.resize(SIZE); }
// No explicit destructor required
// Correct copy semantics also implemented automatically
};
class Main {
public:
Main() : wrapper(new Wrapper()) {}
// Again, no explicit destructor required
// Copying banned for move-only class, so compiler tells you
// if you try to copy it when you can't.
private:
std::unique_ptr<Wrapper> wrapper;
};
This code is guaranteed to execute correctly. When in C++, if you have used new[], delete or delete[], then immediately refactor your code to remove them, and review three times any use of non-placement new- constructing a unique_ptr is pretty much the only valid case. This is nothing but a common, expected outcome of manual memory management.
Since Grizzly isn't answering, I'll put this out there.
Both your Main class and your Wrapper class need properly implemented copy constructors and assignment operators. See The Rule of 3.
The problem is, if your class ever gets copied(which is easy to happen without you even realizing it), then the pointers get copied. Now you've got two objects pointing to the same place. When one of them goes out of scope, it's destructor gets called, which calls delete on that pointer, and the pointed to object gets destroyed. Then the other object is left with a dangling pointer. When it gets destroyed, it tries to call delete again on that pointer.
The lifetime of your wrapper object has ended, but the integer and pointer sub-objects as well as the pointee are still alive. When you invoke delete on the pointer, the pointee's lifetime ends, but the pointer still remains alive. The pointer's lifetime ends after your dtor is complete.
Thus, if your members have become corrupted, there is something else afoot.
Node** nodes;
should be
Node * nodes;
Also the destructor is wrong. It should be:
for(int i = 0; i < numNodes; i++)
delete nodes[i];
delete [] nodes;
There might be other problems as well as e.g. you haven't created a copy constructor or assignment operator so that might make it so that the copy of an object then deletes the object for you.
EDIT: changed the destructor...

Why is the destructor of the class called twice?

Apologies if the question sounds silly, I was following experts in SO and trying some examples myself, and this is one of them. I did try the search option but didn't find an answer for this kind.
class A
{
public:
A(){cout<<"A Contruction"<<endl;}
~A(){cout<<"A destruction"<<endl;}
};
int main()
{
vector<A> t;
t.push_back(A()); // After this line, when the scope of the object is lost.
}
Why is the destructor of the class called twice ?
To add the element a copy constructor is invoked on a temporary object. After the push_back() the temporary object is destroyed - that't the first destructor call. Then vector instance goes out of scope and destroys all the elements stored - that's the second destructor call.
This will show you what's happening:
struct A {
A() { cout << "contruction\n"; }
A(A const& other) { cout << "copy construction\n"; }
~A() { cout << "destruction\n"; }
};
int main() {
vector<A> t;
t.push_back(A());
}
The destructor is called once when the temporary sent to push_back is destroyed and once when the element in t is destroyed.
There are two destructor calls because there are two objects: the argument to push_back, and the newly added element within vector t.
STL containers store copies. In your example the element added to the vector by push_back is copy constructed from the argument passed to push_back. The argument is A(), which is a temporary object, see here (variant 4).
Expanding the answer a bit, altough you havent explicitely asked for it: It might be useful to know when the temporary is destroyed. The standard (N4140) sais it pretty clearly in 12.2 p3:
... Temporary objects are destroyed as the last step in evaluating the
full-expression (1.9) that (lexically) contains the point where they
were created...
Side note: If you use emplace_back there is only one object. The new element in the container is directly constructed from the arguments to emplace_back. Many STL container learned an emplace variant in C++11.
Most probably, copy of your object is getting created. Because of which, the destructor for the copied-object, and for the original-object makes the call-count=2.
Example: Even though, you are passing the object reference, to some class, this internally would invoke the copy-constructor. To avoid this, the child-class (to which you are passing the parent reference, must be as;
Parent *const &p parentRef; //Child.h
Then, the parent object will be passed as;
// Parent.cpp
Parent *parentObj = this;
Child *childObj = Child(parentObj);
Additionally, you can debug the copy-constructor invokation, by overriding;
Parent(const Parent& object){
cout <<"copy called.." << endl;
}
...
More info #stackoverflow#

Destructor called on object when adding it to std::list

I have a Foo object, and a std::list holding instances of it. My problem is that when I add a new instance to the list, it first calls the ctor but then also the dtor. And then the dtor on another instance (according to the this pointer).
A single instance is added to the list but since its dtor (along with its parents) is called, the object cant be used as expected.
Heres some simplified code to illustrate the problem:
#include <iostream>
#include <list>
class Foo
{
public:
Foo()
{
int breakpoint = 0;
}
~Foo()
{
int breakpoint = 0;
}
};
int main()
{
std::list<Foo> li;
li.push_back(Foo());
}
When you push_back() your Foo object, the object is copied to the list's internal data structures, therefore the Dtor and the Ctor of another instance are called.
All standard STL container types in C++ take their items by value, therefore copying them as needed. For example, whenever a vector needs to grow, it is possible that all values in the vector get copied.
Maybe you want to store pointers instead of objects in the list. By doing that, only the pointers get copied instead of the object. But, by doing so, you have to make sure to delete the objects once you are done:
for (std::list<Foo*>::iterator it = list.begin(); it != list.end(); ++it) {
delete *it;
}
list.clear();
Alternatively, you can try to use some kind of 'smart pointer' class, for example from the Boost libraries.
You are creating a temporary Foo here:
li.push_back( Foo() )
push_back copies that Foo into its internal data structures. The temporary Foo is destroyed after push_back has been executed, which will call the destructor.
You will need a proper copy constructor that increases some reference count on the class members that you do not want to destroy early -- or make it private to force yourself on the pointer solution.
Use this object to understand:
class Foo
{
public:
Foo(int x): m_x(x)
{
std::cout << "Constructed Object: " << m_x << ")\n";
}
Foo(Foo const& c): m_x(c.m_x+100)
{
std::cout << "Copied Object: " << m_x << ")\n";
}
~Foo()
{
std::cout << "Destroyed Object: " << m_x << ")\n";
}
};
The First main
std::list<Foo*> li;
li.push_back(Foo(1));
Here we create a temporary Foo object and call push_back(). The temporary object gets copied into the list and the function returns. On completion of this statement the temporary object is then destroyed (via the destructor). When the list is destroyed it will also destroy all the obejcts it contains (Foo is an object with a destructor so destruction includes calling the destructor).
So you should see somthing like this:
Constructed Object: 1
Constructed Object: 101
DestroyedObject: 1
DestroyedObject: 101
In the second example you have:
std::list<Foo*> li;
li.push_back(new Foo(1));
Here you dynamically create an object on the heap. Then call the push_back(). Here the pointer is copied into the list (the pointer has no constructor/destructor) so nothing else happens. The list now contains a pointer to the object on the heap. When the function returns nothing else is done. When the list is destroyed it destroys (note the subtle difference betweens destroy and delete) the object it contains (a pointer) but a pointer has no destructor so nothing happens any you will leak memory.
So you should see somthing like this:
Constructed Object: 1
What actually happens here is that you store a copy of the passed object in the list, because you're sending it by value instead of by reference. So the first dtor that is called is actually called on the object you pass to the push_back method, but a new instance had been created by then and it is now stored in the list.
If you don't want a copy of the Foo object to be created, store pointers to Foo objects in the list instead of the objects themselves. Of course when doing it you will have to properly release memory on destruction of the list.
Making the list holding pointers instead of instances solves the problem with the destructor being called. But I still want to understand why it happens.
#include <iostream>
#include <list>
class Foo
{
public:
Foo()
{
int breakpoint = 0;
}
~Foo()
{
int breakpoint = 0;
}
};
int main()
{
std::list<Foo*> li;
li.push_back(new Foo());
}