首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用新的位置覆盖内存中的对象

用新的位置覆盖内存中的对象
EN

Stack Overflow用户
提问于 2019-04-16 23:00:53
回答 2查看 1.1K关注 0票数 15

我有一个对象,我想把它‘转换’成另一个对象。为此,我在第一个对象上使用了一个placement new,它在自己的地址之上创建另一个类型的新对象。

考虑以下代码:

代码语言:javascript
复制
#include <string>
#include <iostream>

class Animal {
public:
  virtual void voice() = 0;
  virtual void transform(void *animal) = 0;
  virtual ~Animal() = default;;
};

class Cat : public Animal {
public:
  std::string name = "CAT";
  void voice() override {
    std::cout << "MEOW I am a " << name << std::endl;
  }
  void transform(void *animal) override {
  }
};

class Dog : public Animal {
public:
  std::string name = "DOG";
  void voice() override {
    std::cout << "WOOF I am a " << name << std::endl;
  }
  void transform(void *animal) override {
    new(animal) Cat();
  }
};

您可以看到,当使用transform调用Dog时,它会在给定地址之上创建一个新的Cat

接下来,我将使用自己的地址调用Dog::transform

代码语言:javascript
复制
#include <iostream>
#include "Animals.h"

int main() {
  Cat cat{};
  Dog dog{};
  std::cout << "Cat says: ";
  cat.voice() ;
  std::cout << "Dog says: ";
  dog.voice();
  dog.transform(&dog);
  std::cout << "Dog says: ";
  dog.voice();
  std::cout << "Dog address says: ";
  (&dog)->voice();
  return 0;
}

这样做的结果是:

代码语言:javascript
复制
Cat says: MEOW I am a CAT
Dog says: WOOF I am a DOG
Dog says: WOOF I am a CAT
Dog address says: MEOW I am a CAT

我的问题是:

这个操作被认为是安全的,还是会让对象处于不稳定的状态?,,

  1. ,转换后,我调用dog.voice()。它正确地输出了名称CAT (它现在是一只猫),但仍然写着WOOF I am a,即使我认为它应该调用Catvoice方法?(您可以看到,我调用了相同的方法,但通过地址((&dog)->voice()),一切都正常工作。
EN

回答 2

Stack Overflow用户

发布于 2019-04-16 23:13:32

1)不能,这是不安全的,原因如下:

  • 行为未定义,对于某些编译器可能会有所不同。
  • 分配的内存需要足够大以容纳新创建的析构编译器可能会调用原始对象的析构函数,即使它是虚拟的,这将导致泄漏和崩溃。
  • 在您的代码中,原始对象的析构函数未被调用,因此可能导致内存泄漏。

2)我在MSVC2015上观察到,dog.voice()将在不检查实际虚拟表的情况下调用Dog::voice。在第二种情况下,它检查已修改为Cat::voice的虚拟表。但是,正如其他用户所经历的那样,其他一些编译器可能会执行一些优化,并在所有情况下直接调用与声明匹配的方法。

票数 6
EN

Stack Overflow用户

发布于 2019-04-16 23:15:23

这段代码至少有三个问题:

当placement

  • 被调用时,不能保证你正在构造新对象的对象的大小足以容纳这个新对象

  • 你没有调用的对象的析构函数在它的存储空间被重用后使用Dog对象。
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55711220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档