Polymorphism and pointer arrays in c++
#1 Members - Reputation: 138
Posted 26 July 2012 - 02:15 PM
I want a dynamic size to my array, basically then I read in the level it tells me how many objects I need so I do the following:
MObject *objects = new MObject[num_of_obj];
after I find out how many I need through the text file I created that's reading in the level, I find out what KIND of MObjects they are so one of them is a SpeedBoost obj (inherits MOBject)
*(object+obj_counter)= SpeedBoost(args...);
for simplicity sake objcounter is 0 for now
MObject has
virtual Draw();
SpeedBoost has
Draw();
when I attempt to run through a list of objects and call:
objects[loop1].Draw();
the SpeedBoost::Draw() is never called
only the MObject::Draw() is called.
I need it to call the implementation of the Draw for the class that it is not the base class draw.
I'm know that implementing a linked list would probably work but that's added complexity for something that an array should hopefully be able to do.
#2 Members - Reputation: 1864
Posted 26 July 2012 - 02:31 PM
*(object+obj_counter)= SpeedBoost(args...);
You are slicing your SpeedBoost here. The temporary SpeedBoost you create here is truncated to a MObject so it can fit inside the MObject array. Try the following code:
// Create
MObject** objects = new MObject*[num_of_obj];
// Use
objects[0] = new SpeedBoost( ... );
objects[1] = new OtherObject( ... );
// Cleanup
for ( ... )
delete objects[idx];
delete[] objects;
#3 Members - Reputation: 138
Posted 26 July 2012 - 02:49 PM
lets see if I can figure it out. MObject** is a pointer to an array of pointers so it's allocates a slot to each pointer but doesn't allocate them a type yet? so now that they have not be allocated a type we can use new to allocate them to the correct class?
#4 Members - Reputation: 1864
Posted 26 July 2012 - 03:41 PM
MObject** is a pointer to an array of pointers so it's allocates a slot to each pointer but doesn't allocate them a type yet? so now that they have not be allocated a type we can use new to allocate them to the correct class?
Yes. Keep in mind that MObject is an MObject itself, while a MObject* (or MOjbect&) is the MObject interface of an MObject or one of its derived types.
#7 Moderators - Reputation: 7470
Posted 26 July 2012 - 07:59 PM
class Object
{
public:
virtual void Display() const = 0;
};
class IntObject : public Object
{
public:
explicit IntObject(int value)
: MyValue(value)
{ }
virtual void Display() const
{
std::cout << "Integer object: " << MyValue << std::endl;
}
private:
int MyValue;
};
class StringObject : public Object
{
public:
explicit StringObject(const std::string& value)
: MyValue(value)
{ }
virtual void Display() const
{
std::cout << "String object: " << MyValue << std::endl;
}
private:
std::string MyValue;
};
int main()
{
// Also try boost::shared_ptr or boost::scoped_ptr if you're on an outdated compiler
typedef std::vector<std::unique_ptr<Object>> ObjectContainer;
ObjectContainer objects;
// Create us some objects!
objects.push_back(new IntObject(1));
objects.push_back(new StringObject("test"));
// Do stuff the C++11 way
std::for_each(
std::begin(objects),
std::end(objects),
[](const std::unique_ptr<Object>& obj)
{
obj->Display();
}
);
// Alternately, the C++98 way
for(ObjectContainer::const_iterator iter = objects.begin(), end = objects.end(); iter != end; ++iter)
{
(*iter)->Display();
}
// Note: no need to explicitly delete anything!
}My C++11 is still getting into shape, so feel free to nitpick on that bit :-) Also, please feel free to ask any questions this code might raise!
(Note also that this could be done with templates instead of manually creating an IntObject and StringObject, but that seems a bit excessive in the context of the OP's question.)
Edited by ApochPiQ, 26 July 2012 - 08:00 PM.
Accidentally a void.
#8 Members - Reputation: 2759
Posted 26 July 2012 - 09:14 PM
// Do stuff the C++11 way
std::for_each(
std::begin(objects),
std::end(objects),
[](const std::unique_ptr& obj)
{
obj->Display();
}
);
I can't help but feel it's clearer to write it this way (still C++11).
for (const auto& obj: objects)
{
obj->Display();
}
Professional Free Software Developer
#9 Moderators - Reputation: 7470
Posted 26 July 2012 - 10:17 PM
[Work - ArenaNet] [Epoch Language] [Scribblings] [Journal - peek into my shattered mind]
#10 Members - Reputation: 193
Posted 27 July 2012 - 11:22 PM
I think you meant
objects.push_back(std::unique_ptr<Object>(new IntObject(1)));
objects.push_back(std::unique_ptr<Object>(new StringObject("Test")));
Or maybe not, if your compiler doesn't force you to be so verbose. VS10 does.
Also you forgot to give Object a virtual dtor.






