【问题标题】:How to delete an object without having access to it?如何在没有访问权限的情况下删除对象?
【发布时间】:2014-10-25 18:45:17
【问题描述】:

我知道每当我为一个类创建一个新对象时,该对象都会存储在内存中。我也知道,在创建该对象时,它只能在它在(范围可见性)中创建的一组大括号内访问。我需要找到一种方法来删除创建它的大括号之外的那个对象。我已经简要地查看了智能指针,它可能是我想要使用的?我假设它是,我只是不确定。如果智能指针可以满足我的需求,有人可以为我提供一个示例,说明如何使用智能指针访问创建对象之外的对象吗?谢谢:)

编辑:

我正在尝试做的示例:

class ModernWarfare2
{
    //my class
    ModernWarfare2();
};


DWORD XamHook(DWORD r3, DWORD r4, DWORD r5)
{
    switch(XamGetCurrentTitleId())//a function that tells what game is being played
    {
    case Xbox360Dashboard://if i were to exit the game mw2
        {
            if(CODAllocated)//a boolean
            {
                //free the memory of the previous cod game
                if(MW2Allocated)//another boolean
                {
                    delete[] MW2;//gives me an error because i dont have access to MW2
                }
            }
            break;
        }
    case COD_MW2:
        {
            if(!CODAllocated)
            {
                if(!MW2Allocated)
                {
                    ModernWarfare2 *MW2 = new ModernWarfare2();
                }
            }
            break;
        }
    }
    return XamInputGetState(r3,r4,r5);
}

如何解决我的问题?

【问题讨论】:

  • “我也知道,在创建该对象时,该对象只能在创建它的大括号集中访问。”不一定。
  • 我猜我在问什么,我如何在外面访问它?
  • 这听起来很像XY problem
  • 我认为您需要提供一个代码示例,因为我不明白您要做什么。
  • 我添加了我正在尝试做的代码示例。很抱歉缺乏视觉表现。

标签: c++ object visual-c++ memory-management


【解决方案1】:

我还知道,在创建该对象时,该对象只能在创建它的大括号集中访问。

不一定;仅当您构造具有自动存储持续时间的对象时才适用,如下所示:

void foo()
{
    T obj;
}

这样的对象,是的,超出范围。

你动态分配的对象

void foo()
{
    T* obj = new T();
}

这是内存泄漏,因为您从未销毁 *obj;但是,您几乎可以从任何您喜欢的地方访问它:

T* foo()
{
   return new T();
}

void bar()
{
   T* obj = foo();
   // yay!
}

或:

T* obj = nullptr;

void foo()
{
   obj = new T();
}

void bar()
{
   // do stuff with *obj
}

void baz()
{
   foo();
   bar();
}

这一切都变得危险和混乱,因为您最终会得到意大利面条代码,其中动态分配对象的生命周期不清楚,而在上面的示例中,我仍然还没有接近最终摧毁对象的话题。你必须非常小心,不要在你还在使用它的时候破坏它。

这就是智能指针的用武之地,但如果您想要有关使用智能指针的教程,我将不得不将您推荐回您的 C++11 书。

【讨论】:

    【解决方案2】:

    “我还知道,在创建该对象时,该对象只能在创建它的大括号集中访问。” - 这取决于您如何创建对象。

    示例1(大括号外无法访问):

    void func(void)
    {
        Object obj("foo", "bar");
    }
    

    示例 2(可以在大括号外访问):

    Object* func(void)
    {
        Object* obj = new Object("foo", "bar");
        return obj;
    }
    

    可以使用关键字 delete 删除示例 2。

    查看here 以获取有关指针的更多信息。 我个人还没有发现智能指针的用途,但 MSDN 提供了关于该主题的很好信息 here

    【讨论】:

    • 你为什么要写Object obj = Object();
    • 因为您在回答这个问题时正在编写 C# 并且搞砸了;)感谢您指出这一点。
    【解决方案3】:

    通过使用

    创建 MW2
    {
        ModernWarfare2 *MW2 = new ModernWarfare2();
    }
    

    我无法在其他地方引用 MW2。通过这样做,我可以在两个不同的位置创建和删除它:

    class ModernWarfare2
    {
        //my class
        ModernWarfare2();
    };
    
    ModernWarfare2 *MW2 = NULL;
    
    DWORD XamHook(DWORD r3, DWORD r4, DWORD r5)
    {
        switch(XamGetCurrentTitleId())//a function that tells what game is being played
        {
        case Xbox360Dashboard://if i were to exit the game mw2
            {
                if(CODAllocated)//a boolean
                {
                    //free the memory of the previous cod game
                    if(MW2Allocated)//another boolean
                    {
                        delete MW2;//gives me an error because i dont have access to MW2
                    }
                }
                break;
            }
        case COD_MW2:
            {
                if(!CODAllocated)
                {
                    if(!MW2Allocated)
                    {
                        if(MW2 == NULL)
                        {
                            MW2 = new ModernWarfare2();
                        }
                    }
                }
                break;
            }
        }
        return XamInputGetState(r3,r4,r5);
    }
    

    【讨论】:

      【解决方案4】:

      我认为你需要的是基本的设计模式
      使数据和函数成为类的成员

      class SomeHandler
      {
      public:
          void Acquire( /* some source */ );
          void DoSomething( /* eventual parameters */ );
          bool TrySomething(); // returns true if successful
      private:
          void internalFunction();
      
          bool inGoodState;
          SomeType dataINeed;
          SomeOtherType otherData;
      };
      
      void SomeHandler::Acquire( /**/ ) 
      {
          // implement like this
      }
      

      现在函数可以访问所有数据

      像这样使用它

      int main()
      {
          SomeHandler h;
      
          h.Acquire();
          if( h.TrySomething() )
          {
              h.DoSomething();
          }
      }
      

      【讨论】:

        【解决方案5】:

        根据您的代码 sn-p,您必须将指针 MW2 保存为 未来,以便您可以删除指针。

        我建议你改变

        if(!MW2Allocated)
        

        if(!MW2)
        

        这样您就不必创建另一个变量来保存对分配的内存的引用 当然,你必须移动

        ModernWarfare2 *MW2
        

        到更大的范围(将其移动到与 MW2Allocated 相同的范围)并将其初始化为 NULL。 如果您使用 C++11 支持的编译器,请使用“nullptr”而不是“NULL”。

        还要确保你使用

        delete
        

        而不是

        delete[]
        

        因为这不是数组分配

        我认为您不能使用智能指针来跳过保存对分配内存的引用, 因为它们旨在使内存删除自动或确保不会发生两次删除 为相同的记忆。 参考 http://www.codeproject.com/Articles/541067/Cplusplus-Smart-Pointers 关于智能指针的一个很好的解释

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-03
          • 2011-10-23
          相关资源
          最近更新 更多