C++ C++;:初始化成员数据时的奇怪行为

C++ C++;:初始化成员数据时的奇怪行为,c++,c++11,pointers,memory-management,C++,C++11,Pointers,Memory Management,我遇到了一个关于C++17静态内联成员数据的奇怪行为 有实现抽象类: class Implementation { public: virtual void call() = 0; }; class Example : public Implementation { public: void call() override { cout << "Called Example::call function!" << endl; } }; clas

我遇到了一个关于
C++17静态内联成员数据的奇怪行为

实现
抽象类:

class Implementation
{
public:
  virtual void call() = 0;
};
class Example : public Implementation
{
public:
  void call() override
  {
    cout << "Called Example::call function!" << endl;
  }
};

class AnotherExample : public Implementation
{
public:
  void call() override
  {
    cout << "Called AnotherExample::call function!" << endl;
  }
};
示例
另一个示例
类实现了抽象类:

class Implementation
{
public:
  virtual void call() = 0;
};
class Example : public Implementation
{
public:
  void call() override
  {
    cout << "Called Example::call function!" << endl;
  }
};

class AnotherExample : public Implementation
{
public:
  void call() override
  {
    cout << "Called AnotherExample::call function!" << endl;
  }
};
使用:

Implementer::get_example(true)->call(); // This expect to return example.
Implementer::get_example(false)->call(); // This expect to return another_example.
我们希望看到:

Called Example::call function!
Called AnotherExample::call function!
Called AnotherExample::call function!
Called AnotherExample::call function!
但我们看到:

Called Example::call function!
Called AnotherExample::call function!
Called AnotherExample::call function!
Called AnotherExample::call function!
我不明白。
example
object如何获取另一个示例对象的值?

编辑:如果进行更改,我们可以获得所需的输出

static inline Implementation* example = unique_ptr<Example>(new Example).get();
静态内联实现*example=unique_ptr(新示例).get();

static inline unique_ptr示例=unique_ptr(新示例);
唯一的ptr(新示例).get()
将在分配
get()
的结果后立即销毁新的
Example
实例(感谢@JVApen的更正)

从那时起,可能会发生很多奇怪的事情

例如,
newanotherexample
分配的对象可以(而且很可能会)放在第一个对象所在的内存中,第一个指针会突然再次指向有效的活动对象

不确定这是否是一种现象,但发生的情况非常相似——你认为你看到的是A,但它是不同的A

我会先把它清理干净


Coliru sandbox

实际上,当get返回值时,该值仍然有效。只有在序列点(read;)临时变量才超出范围。因此,分配将首先发生,然后unique_ptr超出范围。@bobah为什么
unique_ptrIt会这样做,但内存仍然没有损坏或返回到操作系统,因此进程不会被终止。实际上,我问如果
ABC
class实现继承
Abstract
class(),为什么内存会损坏,但是如果
ABC
class不实现继承
Abstract
class(),内存仍然没有损坏?如果您检查代码,我们会看到
调用ABC::call函数消息,但在另一个代码中看不到相同的消息。这可能是一项昂贵的研究。使用C/C++时,您通常只会假设如果程序不正确或行为“未定义”,那么任何事情都可能发生。一个悬而未决的猜测是,具有虚拟表的类更大,并且触发了一些内存回收机制,而更基本的类则不是;同样的情况也会发生在正则成员上,或者任何创建临时唯一\u ptr并稍后访问指针的表达式上。(它实际上类似于std::string::c_str()中更老、相同的问题)。你能修改标题和标签吗?我可以做到,但我觉得如果我只是简单地“控制”一下就太过分了。