继承和记忆-它们是如何一起工作的
inheritance and memcpy - How is it work together?
我有这样的代码:
#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;
}
行:c->Print():前面的一行c变成了老虎,为什么打印这一行给我:罗斯,速度135081本月的速度3的罗斯为什么会有记忆问题?为什么叫老虎的打印方法而不叫猫的打印方法?
它不一起工作。
在这些对象上使用memcpy
会产生未定义的行为,标准允许任何事情发生。
导致问题的不是继承本身,而是虚成员函数或自定义构造函数/析构函数的存在。这使得您的对象失去了可复制的分类,而在使用memcpy
时是必需的。
你的类不是trivial -copyable的第二个原因——它包含一个类型为std::string
的成员,它不是trivial -copyable。
实际上,当您执行std::string
子对象的位拷贝时,您最终会得到指向同一内存的两个指针,并且两个string
对象都会尝试释放这个指针。这会使你的程序崩溃。如果在v表上没有使用memcpy
,
但是当你混合优化时,甚至会发生更奇怪的事情。这就是未定义行为的含义。
您应该避免对c++
中的对象使用memcpy,而应使用复制构造函数。
相关文章:
- 如何使我的 sizeof sum 结构与空参数包一起工作
- SFINAE:它如何与派生类一起工作?
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- 尝试让条形码扫描仪与Arduino一起工作
- 从书本中学习C++无法使该程序与类一起工作
- 让类与运算符一起工作更简单的方法
- 如何使lambda与std::nullopt一起工作
- 当我使用长整型时,我的代码不起作用,它与 int 一起工作得很好
- 返回对象如何与分配运算符一起工作
- GLM :: perspective()和glm :: lookat()一起工作
- SFML OpenGL:如何同时与他们一起工作
- 使QTConcurrent ::映射与Lambdas一起工作
- 如何与C 字符串中的非ASCII字符一起工作
- 我如何适应擦除式习惯与矢量元组一起工作
- 需要帮助使 VOID 代码与总工资一起工作
- 我怎样才能让这个刽子手代码与 wxDev-C++ 一起工作
- Googletest 在 bazel test 中永远不会失败(在它应该失败的地方),但与 cmake & clion 一起工作
- 常量变量初始化仅与成员初始化列表一起工作
- feal_ptr与unique_ptr一起工作
- OpenGL Ping Pong可与一张通行证一起工作,而不是两个通行证