关于堆和堆栈应用程序问题

On heap and on stack application issue

本文关键字:应用程序 问题 堆栈 于堆      更新时间:2023-10-16

我在堆上创建系统对象,在系统类中,我在堆上创建游戏对象,而键盘服务器对象在堆栈上。

1)键盘服务器对象的行为是否像堆上一样,因为系统对象是它的一部分?

2)键盘服务器对象也需要在堆上创建吗?

3)是否有更好的解决方案来提高性能?

////////////////////////////////////////////////////////////////////////////////
// Filename: main.cpp
////////////////////////////////////////////////////////////////////////////////
#include "SystemClass.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow )
{
    SystemClass* System;
    bool result;
    // Create the system object
    System = new SystemClass;
    if ( !System )
    {
        return 0;
    }
    // Initialize and run the system object
    result = System->Initialize();
    if (result)
    {
        System->Run();
    }
    // Shutdown and release the system object
    System->Shutdown();
    delete System;
    System = 0;
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
// Filename: SystemClass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _SYSTEMCLASS_H_
#define _SYSTEMCLASS_H_

///////////////////////////////
// PRE-PROCESSING DIRECTIVES //
///////////////////////////////
#define WIN32_LEAN_AND_MEAN

//////////////
// INCLUDES //
//////////////
#include <Windows.h>

///////////////////////
// MY CLASS INCLUDES //
///////////////////////
#include "GameClass.h"
#include "KeyboardClass.h"

////////////////////////////////////////////////////////////////////////////////
// Class name: SystemClass
////////////////////////////////////////////////////////////////////////////////
class SystemClass
{
    public:
    SystemClass();
    ~SystemClass();
    bool Initialize();
    void Shutdown();
    void Run();
    LRESULT CALLBACK MessageHandler( HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam );
private:
    void InitializeWindows();
    void ShutdownWindows();
private:
    LPCSTR m_applicationName;
    HINSTANCE m_hinstance;
    HWND m_hwnd;
    GameClass*            m_Game;
    KeyboardServerClass  m_KeyboardServer;
};

/////////////////////////
// FUNCTION PROTOTYPES //
/////////////////////////
static LRESULT CALLBACK WndProc( HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam );

/////////////
// GLOBALS //
/////////////
static SystemClass* ApplicationHandle = 0;
#endif

////////////////////////////////////////////////////////////////////////////////
// Filename: KeyboardClass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _KEYBOARDCLASS_H_
#define _KEYBOARDCLASS_H_

////////////////////////////////////////////////////////////////////////////////
// Class prototype
////////////////////////////////////////////////////////////////////////////////
class KeyboardServerClass;

////////////////////////////////////////////////////////////////////////////////
// Class name: KeyboardClientClass
////////////////////////////////////////////////////////////////////////////////
class KeyboardClientClass
{
public:
    KeyboardClientClass( const KeyboardServerClass& KeyboardServer );
    ~KeyboardClientClass();
    bool KeyIsPressed( unsigned char keycode ) const;
private:
    const KeyboardServerClass& server;
};
class KeyboardServerClass
{
    friend KeyboardClientClass;
public:
    KeyboardServerClass();
    void OnKeyPressed( unsigned char keycode );
    void OnKeyReleased( unsigned char keycode );
private:
    static const int nKeys = 256;
    bool keystates[ nKeys ];
};
#endif

1)键盘服务器对象的行为是否像堆上一样,因为系统对象是它的一部分?

不,KeyboardServerSystemClass的一部分,反之亦然。

2)键盘服务器对象也需要在堆上创建吗?

它是自动创建的:

m_KeyboardServerSystemClass的一部分。当您创建SystemClass 时,它将创建KeyboardServerClass对象。

因此,当您在堆上创建SystemClass对象时,它将自动为您在堆上创建m_KeyboardServer

想象一下这样的场景:

class A
{
   int field;
};
A *a = new A();
A b;

在这里,对象a是在堆上创建的,其成员field也是如此。对象b是在堆栈上创建的,因此b.field是这样。

另外,想象一下:

class A
{
    Object* obj;
}

如果在堆栈上创建此类的对象,则指向Object指针将在堆栈上分配。此指针指向的完整Object可能在堆上、可能在堆栈上、某个文件中等,但类的一部分是指向 Object 的指针,它将存储在存储整个class A对象的同一位置。

3 有什么更好的解决方案来提高性能吗?

如果您有 *m_KeyboardServer并且您总是手动分配新实例,那么它不会比将整个对象放在类中慢,这将自动为您初始化一个对象。但是,如果您不需要不同的 KeyboardServer 实例(如果您想在不同的 SystemClass 对象之间共享一个实例,那么您应该使用指针,因为它只会为每个 SystemClass 实例创建一个指针。