虚函数的内存位置

Memory location for virtual functions

假设我有 base.h class

#ifndef BASE_H
#define BASE_H

class base
{
public:
    base(){}
    virtual void id() const{ std::cout << "base\n"; }
    virtual ~base(){}
protected:
private:
};

#endif // BASE_H

和 derived.h class

#ifndef DERIVED_H
#define DERIVED_H

#include <base.h>

class derived : public base
{
public:
    derived(){}
    void id() const{ std::cout << "derived\n"; }
protected:
private:
};

#endif // DERIVED_H

我开始测试在主程序中包含此代码的不同结果

int main()
{
    base* bas;
    derived* der;
    base statbas;
    derived statder;

    *bas = statbas;   // here it crashes

    bas = new base;   

    *bas=statbas;     // here it works. It also worked with bas=&statbas;

    bas->id();

    return 0;
}

看来我需要为指针分配一些内存bas否则程序会崩溃。这件事让我感到困惑,主要是因为我无法想象为一个没有任何变量(class 基数仅由函数形成)的对象(在本例中为 bas)存储内存。

另一件让我感到困惑的事情是显然 *bas=statbas(bas 指向 statbas)和 bas=&statbas(bas 具有 statbas 的内存地址)不相等,实际上第一个使程序在第二个工作时崩溃。

我假设所有这些问题都与基础 class 中的虚拟函数有关,事实上,当 id() 未声明为虚拟时,程序不会崩溃(但显然不起作用也正确)。

有人可以让我明白在这种情况下如何管理内存吗?

当您取消引用指针时,它应该指向某物。你的根本没有初始化。

要使指针指向自动变量的地址,您应该使用 take its address as bas = &statbas

It seems that I need to allocate some memory for the pointer bas otherwise the program will crash. This thing confuses me mainly because I cannot imagine to store memory for an object (bas in this case) that does not have any variables (the class base is formed just by functions).

当您声明一个指针时,无论类型如何,它最初都不指向任何地方。

int* p;

给这样的指针赋值肯定会和写入一样崩溃

int n;

正在创建一个具有任意值的变量 n。

Another thing that confuses me it's that apparently *bas=statbas (bas points to statbas) and bas=&statbas (bas has the memory address of statbas) are not equal, in fact the first makes the program to crash while the second works.

如果 bas 会指向某个地方那么

*bas = statbase;

会把 statbase 的内容复制到 bas 指向的地方,因为 bas 没有指向任何特定的地方,你会崩溃。

写作

 bas = &statbase;

是有效的,因为 bas 是一个指针,您将其指定为指向 'base' 的实例,即 statbase.

I assume all these issues are connected to the function which is virtual in the base class, indeed when id is not declared as virtual the program does not crash (but obviously does not work correctly either).

你想错了,所有这些问题都与内存管理和指针有关。

*bas = statbas;   // here it crashes

因为您取消引用了未初始化的 bas,因此您得到了未定义的行为。

bas = new base;
*bas=statbas;     // here it works. It also worked with bas=&statbas;

之所以有效,是因为 bas 已在前一行初始化并指向内存中的有效对象。bas=&statbas 执行其他操作。它分配 bas 指向另一个对象,导致新分配的对象泄漏,因为它不再被任何东西指向,因此永远无法删除。

It seems that I need to allocate some memory for the pointer bas otherwise the program will crash.

正确。

This thing confuses me mainly because I cannot imagine to store memory for an object (bas in this case) that does not have any variables (the class base is formed just by functions).

您可以为没有成员的对象分配内存,其方式与为有成员的对象分配内存的方式完全相同。

Another thing that confuses me it's that apparently *bas=statbas (bas points to statbas) and bas=&statbas (bas has the memory address of statbas) are not equal, in fact the first makes the program to crash while the second works.

第一个不是这样做的。第一个取消引用 bas,然后将 statbas 复制到取消引用的对象。第二个设置 bas 指向 statbas.

I assume all these issues are connected to the function which is virtual in the base class, indeed when id is not declared as virtual the program does not crash (but obviously does not work correctly either).

不,问题与虚函数无关。您只需取消引用一个未初始化的指针。虚拟性恰好是幸运地导致未定义行为不同的东西。