I have this code:
#include <iostream>
#include <string>
#include <cstring>
class Animal
{
public:
Animal(const std::string &name) : _name(name)
{
}
virtual void Print() const = 0;
virtual ~Animal() {}
protected:
std::string _name;
};
class Dog : public Animal
{
public:
Dog(const std::string &name, const std::string &dogtype) : Animal(name), _dogtype(dogtype)
{
Print();
}
void Print() const
{
std::cout << _name << " of type " << _dogtype << std::endl;
}
private:
std::string _dogtype;
};
class Cat : public Animal
{
public:
Cat(const std::string &name, int weight) : Animal(name), _weight(weight)
{
Print();
}
virtual void Print() const
{
std::cout << _name << " of weight " << _weight << std::endl;
}
virtual ~Cat(){}
private:
int _weight;
};
class Tiger : public Cat
{
public:
Tiger(const std::string &name, int weight, double speed) : Cat(name, weight), _speed(speed)
{
Print();
}
void Print() const
{
std::cout << _name << " speed " << _speed << std::endl;
}
virtual ~Tiger(){std::cout << "Tiger's dtor" << std::endl;}
private:
int _speed;
};
int main()
{
Animal *a = new Tiger("theRealKing", 3, 40.5);
Cat *c = new Cat("silvester", 4);
memcpy(c, a, sizeof(Cat));
c->Print(); /// ------------------------
delete a;
delete c;
return 0;
}
in the line : c->Print(): the line before that c became a tiger so why does it print me this line : Ross with speed 135081 insted of Ross with speed 3 why there is a memory problem ? why does it call the print method of tiger and not of cat ?
It doesn't work together.
Using memcpy
on these objects produces undefined behavior, the Standard permits anything to happen.
It isn't inheritance per se that is causing you problems, but the presence of virtual member functions or custom constructor/destructor. These make your objects lose the trivially-copyable classification that is required when using memcpy
.
Your class isn't trivially-copyable for a second reason -- it contains a member of type std::string
which is not trivially-copyable.
In practical terms, when you perform a bitwise copy of a std::string
subobject, you end up with two pointers to the same memory, and both string
objects will try to free this pointer. That will crash your program. If using memcpy
on a v-table hasn't done so earlier.
But when you mix in optimizations, even weirder things can happen. That's what undefined behavior means.
You should avoid using memcpy for objects in c++
, use the copy constructor instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With