2014-10-25 4 views
1

Я знаю, что всякий раз, когда я создаю новый объект для класса, этот объект хранится в памяти. Я также знаю, что при создании этого объекта его можно получить только в пределах набора фигурных скобок, в котором он создан (видимость видимости). Мне нужно найти способ удалить этот объект за пределами скобок, в котором он создан. Я кратко рассмотрел интеллектуальные указатели, и возможно, это то, что я хочу использовать? Я предполагаю, что это так, я просто не знаю точно. Если интеллектуальный указатель может удовлетворить мои потребности, попросил бы кто-нибудь дать мне пример того, как использовать интеллектуальный указатель для доступа к объекту за пределами того места, где он был создан? Спасибо :)Как удалить объект без доступа к нему?

EDIT:

Пример того, что я пытаюсь сделать:

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); 
} 

Как исправить мою проблему?

+0

_ «Я также знаю, что при создании этого объекта доступ к объекту возможен только в пределах набора фигурных скобок, в котором он создан.» _ Не обязательно. –

+1

Я предполагаю, что я спрашиваю, как мне получить доступ к нему за пределами? – user3343925

+0

Это очень похоже на проблему [** XY **] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – juanchopanza

ответ

5

Я также знаю, что при создании этого объекта, объект может быть доступен только в наборе скобок он создается в

Не обязательно. это только справедливо, когда вы создаете объекты с автоматической продолжительности хранения, например:

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.

+0

@Boann whoops .. –

1

«Я также знаю, что при создании этого объекта доступ к объекту возможен только в пределах набора фигурных скобок, в котором он создан». - Это зависит от того, как вы создаете объект.

Пример 1 (не могут быть доступны за пределами скобки):

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

Пример 2 (могут быть доступны за пределами скобок):

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

Пример 2 могут быть удалены с помощью ключевого слова удалить.

Взгляните на here для получения дополнительной информации о указателях. я лично не нашел применение для смарт-указатели, но MSDN содержит полезную информацию по теме here

+3

Зачем вам писать 'Object obj = Object();'? –

+1

Потому что вы пишете C# во время ответа на этот вопрос и перепутались;) Спасибо, что указали, что один из них. – jProg2015

+0

он –

-1

Основываясь на фрагменте кода, вы должны сохранить указатель MW2 для будущем, так что вы можете удалить указатель.

Я хотел бы предложить вам изменить

if(!MW2Allocated) 

в

if(!MW2) 

так, что вам не нужно, чтобы создать еще одну переменную для сохранения ссылки на вашей выделенной памяти Offcourse вы должны двигаться

ModernWarfare2 *MW2 

для увеличения объема (переместите его в область действия, такую ​​же, как и MW2Allocated) и инициализировать его до NULL. Используйте «nullptr» вместо «NULL», если вы используете поддерживаемый C++ 11 компилятор.

Makesure Также вы используете

delete 

вместо

delete[] 

, так как это не выделение массива

Я не думаю, что вы можете использовать смарт-указатели, чтобы пропустить сохранение вашей ссылки в выделенную память, , поскольку они предназначены для автоматического удаления памяти или для обеспечения отсутствия двух удалений. для той же памяти. См http://www.codeproject.com/Articles/541067/Cplusplus-Smart-Pointers хорошее объяснение о смарт-указатели

0

Создавая 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); 
} 
0

Я думаю, что вам нужно, это основной шаблон проектирования
Сделать данные и функции членов класса

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(); 
    } 
}