sábado, 29 de março de 2008

MS VS 2005 C++ :: Uso de array de ponteiros para objetos de uma classe

 

Conforme apresentada inicialmente a solução do projeto "Estatísticas" em MS VS 2005 C++, alguns tropeços aconteceram quanto ao uso de array de ponteiros para objetos de uma classe.

Pesquisando um pouco mais, o link abaixo mostra alguma luz para esse problema:

http://msdn.microsoft.com/vstudio/tour/vs2005_guided_tour/VS2005pro/Framework/CPlusLanguageFeatures.htm

 

No projeto, as modificações foram feitas nos seguintes trechos:

 

1) Declaração do array de objetos gerenciáveis da classe "Estatisticas":

#pragma once

#include <stdio.h>

#include "Estatisticas.h"

namespace oop1a {

    // A declaração a seguir foi substituída por outra logo mais abaixo nos atributos da classe Form1

    //Estatisticas *detalhada[27];          

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::Runtime::InteropServices;

    /// <summary>
    /// Summary for Form1
    ///
    /// WARNING: If you change the name of this class, you will need to change the
    ///          'Resource File Name' property for the managed resource compiler tool
    ///          associated with all .resx files this class depends on.  Otherwise,
    ///          the designers will not be able to interact properly with localized
    ///          resources associated with this form.
    /// </summary>


    public ref class Form1 : public System::Windows::Forms::Form
    {
    private:

        // Declaração de ponteiro para objeto gerenciável pelo DOT-NET FRAMEWORK

        Estatisticas   ^geral;

        FILE *fh;
        int uf, qtd;
        bool abrir;

        // Outra maneira de declarar um array de ponteiros para objetos de uma classe
        // Declaração de um array de ponteiros para objetos gerenciáveis da classe Estatisticas
        // Atenção: ver modificação da classe no arquivo "Estatisticas.h"

        array<Estatisticas^>    ^detalhada;

    public:
        Form1(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }

    protected:
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        ~Form1()
        {
            if (components)
            {
                delete components;
            }
        }

 

2) Instanciando e destruindo os objetos gerenciáveis:

private: System::Void button3_Click(System::Object^  sender, System::EventArgs^  e) {

                  // botão Estatística Detalhada

                 int i;

                 if ( abrir == false ) return;
                 // converter string em char e abrir o arquivo

                 System::String ^ filename = openFileDialog1->FileName ;

                 char* filenameANSI = (char*)(void*)Marshal::StringToHGlobalAnsi(filename);

                 fh = fopen( filenameANSI, "r" );

                 Marshal::FreeHGlobal( (IntPtr)filenameANSI );

                 // Instanciar um array de 27 elementos do tipo Estatisticas^
                 // Estatisticas^ necessita ser uma classe para objetos gerenciáveis
                 // Usa-se "gcnew" no lugar de "new" para objetos gerenciáveis
                 // Define-se "gcnew" como "garbage collector new"
                 // Nenhum objeto do array é instanciado nesta etapa
                 // Atenção: ver modificação da classe no arquivo "Estatisticas.h"

                 detalhada = gcnew array<Estatisticas^>(27);

                 // instanciamento de cada objeto do array através do "gcnew"

                 for (i = 0; i < 27; i++)
                 {
                         detalhada[i] = gcnew Estatisticas();
                 }

                 while ( true ){

                        fscanf(fh, "%d %d", &uf, &qtd);

                        if ( uf == 0 ) break;

                        detalhada[ uf - 1 ]->Acumular( qtd );
                 }

                 geral->Calcular();

                 listBox1->Items->Clear();

                 for (i = 0; i < 27; i++){

                        detalhada[i]->Calcular();

                        listBox1->Items->Add( "Média[" +
                                      System::Convert::ToString(i + 1) + "]: " +
                                      System::Convert::ToString( detalhada[i]->media ) );

                 }

                 fclose( fh );

                 // destruir o array de objetos gerenciáveis

                 delete[]   detalhada;

         }

 

3) Modificação necessária na declaração da interface da classe "Estatisticas":

// Estatisticas.h

// É requerido declarar a classe como "ref" para trabalhar com objetos gerenciáveis pelo dot-net

ref   class   Estatisticas {

    public: int cnt;
    public: int somatoria;
    public: int media;

    Estatisticas( );         // Construtor

    public: void Acumular( int );
    public: void Calcular( );

    ~Estatisticas( );        // Destrutor

};

 

4) Resumindo, desta maneira os conceitos de OOP trabalhados e aplicados em projetos desenvolvidos no MS VS 2005 C++:

array<Estatisticas^>    ^detalhada;                     // declaração

detalhada = gcnew array<Estatisticas^>(27);     // instanciamento do array

for (i = 0; i < 27; i++)
{
       this->detalhada[i] = gcnew Estatisticas();    // instanciar objeto [i]
                                                                               //
individualmente
}

delete[] detalhada;                                                // destruição

Agora, no CBuilder para fazer o mesmo:

Estatistica    *detalhada[27];                                // declaração

for (i = 0; i < 27; i++){
       detalhada[i] = new Estatistica();                   // instanciar objeto [i]
                                                                               // individualmente
}

delete [] detalhada;                                              // destruição

 

Até mais.

Nenhum comentário: