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()中更老、相同的问题)。你能修改标题和标签吗?我可以做到,但我觉得如果我只是简单地“控制”一下就太过分了。