Класс C ++ Ref не является членом System :: IDisposable; проблемы с реализацией IDisposable - PullRequest
3 голосов
/ 07 февраля 2010

Я хочу создать глобальный вектор из своего собственного класса объектов, который называется «Персона». Тем не менее, компилятор говорит, что

    error C2039: '{dtor}' : is not a member of 'System::IDisposable'
1>        c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable'

Итак, я посмотрел, как реализовать IDisposable (который, как я теперь знаю, используется в основном для неуправляемых ресурсов), но все еще не может реализовать его со следующим:

ref class Globals : System::IDisposable
{  
public: 
  static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
    void Dispose()
    {
         delete person_data;
    }
}; 

2 ошибки, которые я получаю:

error C2605: 'Dispose' : this method is reserved within a managed class
1>        did you intend to define a destructor?
error C3766: 'Globals' must provide an implementation for the interface method 'void System::IDisposable::Dispose(void)'
1>        c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable::Dispose'

Ответы [ 5 ]

3 голосов
/ 08 февраля 2010

Вам не нужно явно наследовать от IDisposable. Следуя MSDN doco , используйте следующий шаблон:

ref class Globals
{
public:
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
    !Globals() // finalizer
    {
        delete person_data;
    {
protected:
    ~Globals() // destructor calls finalizer
    {
        this->!Globals();
    }
};
0 голосов
/ 23 февраля 2010

Вам не нужно реализовывать Dispose () самостоятельно, напрямую или через деструктор. Неявно созданный деструктор уже уничтожает все объекты-члены. Интерфейс IDisposable будет добавлен автоматически, не упоминайте об этом явно.

Далее вам нужно решить, является ли person_data дескриптором (который должен быть установлен для экземпляра, созданного с помощью gcnew) или семантикой объекта-члена (например, семантикой стека, конструктор автоматически вызывается конструктором родительского объекта) объект, деструктор вызывается автоматически, когда заканчивается время жизни родительского объекта, и вы используете "." вместо "->" для доступа к членам).

Кроме того, вы уверены, что хотите, чтобы одна копия person_data была передана всем экземплярам «Globals», но была уничтожена первым экземпляром, который должен быть удален, а остальные экземпляры содержали недопустимую ссылку (ссылку на удаленный объект)? Похоже, вы пытаетесь использовать анти-паттерн Singleton, верно?

0 голосов
/ 08 февраля 2010

С C ++ / CLI в действии Шаблон C ++ / CLI Dispose имеет следующие правила (перефразировано):

  • Если класс имеет финализатор или деструктор компилятор генерирует Dispose(bool) это вызовет либо финализатор или деструктор на основе значение bool.
  • Если он имеет только d'tor (~ тип), то компилятор вызывает Удалите (true), чтобы вызывать d'tor.
  • Если он имеет только финализатор (! Type) тогда компилятор вызывает Dispose (false), чтобы финализатор называется

Также для второго правила: компилятор реализует для вас интерфейс IDisposable (сгенерировав Dispose()). Затем он использует SuppressFinalize, чтобы убедиться, что финализатор не вызван.

Я сделал это с вашим кодом, и единственный способ заставить его скомпилировать - сделать person_data членом экземпляра. Ошибка, которую я получил, когда она была статической, была error C2039: '{dtor}' : is not a member of 'System::IDisposable', что не имеет особого смысла.

Кроме того, вам даже нужно delete вектор person_data, поскольку это управляемый объект? Может быть, вы делаете, но я не использовал достаточно текста, чтобы сказать.

Редактировать Возможно, первый абзац этой статьи содержит ответ (выделено мной):

Когда вы объявляете переменную-член как статическое и когда приложение запускается, компилятор создает копию этот член. Этот участник будет поддерживается компилятором в то время как Программа запущена. Если вы объявите экземпляр класса, как указано выше переменная транспортного средства, статический член не часть объекта: компилятор создает и поддерживает статический член, используете ли вы его или нет, объявляете ли вы переменную класса или нет.

0 голосов
/ 08 февраля 2010

используйте финализатор, как показано на http://www.codeproject.com/KB/mcpp/cppclidtors.aspx

0 голосов
/ 07 февраля 2010

Используйте деструктор. В C ++ / CLI ~ ClassName () является Dispose (), а! ClassName () эквивалентно C # ~ ClassName (). В вашем случае:

ref class Globals : System::IDisposable
{  
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
    void ~Globals()
    {
        delete person_data;
    }
}; 
...