虚拟功能的内存位置

时间:2015-02-16 14:03:55

标签: c++ inheritance memory-management virtual

假设我有base.h类

#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类

#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分配一些内存,否则程序将崩溃。这件事让我困惑,主要是因为我无法想象为一个没有任何变量的对象(在这种情况下为bas)存储内存(类库只是由函数构成)。

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

我假设所有这些问题都与基类中的虚函数相关联,实际上当id()未声明为虚拟时,程序不会崩溃(但显然也无法正常工作)。

在这种情况下,有人可以清楚地了解如何管理内存吗?

3 个答案:

答案 0 :(得分:1)

*bas = statbas;   // here it crashes

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

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

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

  

似乎我需要为指针bas分配一些内存,否则程序会崩溃。

正确。

  

这件事让我感到困惑,主要是因为我无法想象为一个没有任何变量的对象(在这种情况下为bas)存储内存(类库只是由函数构成)。

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

  

让我感到困惑的另一件事就是显然* bas = statbas(bas point to statbas)和bas =&amp; statbas(bas有statbas的内存地址)不相等,实际上第一个让程序崩溃而第二部作品。

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

  

我假设所有这些问题都与基类中的虚函数相关联,实际上当id未声明为虚拟时,程序不会崩溃(但显然也无法正常工作)。

不,这个问题并没有真正与虚拟功能相关联。您只需取消引用未初始化的指针即可。虚拟性碰巧是幸运地导致未定义的行为不同。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

  

似乎我需要为指针bas分配一些内存   否则程序会崩溃。这件事主要让我困惑   因为我无法想象为对象存储内存(在此基础上)   case)没有任何变量(类库是刚刚形成的   通过功能)。

当你声明一个指针时,无论它是什么类型,它最初都没有指向任何地方。

int* p;

分配给这样的指针肯定会像写

一样崩溃
int n;

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

  

另一件令我困惑的事情显然是* bas = statbas(bas   指向statbas)和bas =&amp; statbas(bas的内存地址为   statbas)不相等,实际上第一个使程序崩溃   而第二个工作。

如果bas会指向某处

*bas = statbase;

会将statbase的内容复制到bas指向的位置,因为bas并没有指向任何特定的崩溃位置。

 bas = &statbase;

是有效的,因为bas是一个指针,你指定它指向'base'的实例,即statbase

  

我认为所有这些问题都与功能有关   在基类中虚拟,实际上当id未声明为虚拟时   程序不会崩溃(但显然无法正常工作   任一)。

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