Массивы экземпляров класса

Тема в разделе "Общие вопросы по С и С++", создана пользователем eugira, 21 мар 2007.

  1. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    Как в массиве или коллекции хранить экземпляры классов?
    Очень часто есть необходимость создания множества экземпляров классов (заранее неизвестно сколько). И для обращения к методам и свойствам любого экземпляра их хранить либо в динамическом массиве либо в коллекции.

    Проблема в том, что в C++ нет оператора аналогичного Redim в VB
    Если в среде NET будь то VB NET или C++ есть коллекция ArrayList
    Пишешь на VB без проблем
    Dim coll As New ArrayList, w As Book 'экземпляр класса Book
    For i = 0 To n
    Dim w As New Служаший(nm(i), i+100)
    coll.Add(w)
    next i
    coll(3).Оклад(); //далее без проблем у любого элемента коллекции вызываешь метод класса
    //несм на то что это элем коллекции , он автом преобразуется к типу класса

    На С++ подобное у меня вызывает ряд проблем
    1)во первых если пишем в NET то, слава богу есть ArrayList (в С++ Builder его нет). Что STL-библиотеку подключать, что-ли?
    2)если на NET то код
    using namespace System;
    using namespace System::Collections; //
    …..
    book * b; ArrayList * st;
    for (int i=0;i<5;i++)
    {
    b=new book("title",i+100);
    st->Add(b);
    }
    То компилятор выдаёт ошибку
    Add' : cannot convert parameter 1 from 'book *' to 'System::Object __gc *'

    Если попытаться обойтись вообще без коллекций только динамическим массивом
    book * b;
    b=new book[5];//ошибка – в классе Book нет конструктора без параметров
    //а почему он собственно должен быть?
    Возможно выходом было бы использование приёма хранения экземпляров созданных объектов в статическом массиве класса (т.е внутри класса)?

    Как вообще на C++ программисты управляются с множкством объектом класса?
     
  2. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Программисты на С++ читают страуструпа сначала, и вникают в концепцию указателей, конструкторов и прочих сложных терминов.

    1. .NET не пользуюсь, и хелп лень открывать, но навскидку предположу что там написано что ArrayList предназначен для хранения указателей на базовый System::Object. Хотя по следам прочтенной книжки - вроде бы там все классы наследуются от него? Ну да ладно.

    2. Конструктор без параметров, видимо, нужен для того, чтобы инициализировать 5 объектов, которые вы создали вызовом new book[5]. А что, по-вашему, должно быть внутри этих объектов после создания?

    Как управляться? Да как хочешь: хочешь - пиши свой велосипед, хочешь - используй STL, или другие расширения. Встроенного в язык динамического массива тут действительно нет. Но все средства разработки с радостью предложат альтернативу - будь то ArrayList, СArray или vector.
     
  3. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    grigsoft уже все сказал
     
  4. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    В поставленном мной вопросе я хотел фактически сказать по-моему довольно важную вещь.
    Жаль, что такая негативная реакция.
    Если
    1) разрабатываемый класс на C++ должен иметь много реализаций
    2) Некоторые его методы должны возвращать не одно а массив или список значений

    То реализация данного класса существенно зависит от среды разработки, будь то древний Borland C++ 3.1 или С++ Builder или MS Visual C++ 6.0 или NET C++
    .Т.е невозможно или трудно спроектировать универсальный класс, отвечающий
    требованиям 1), 2) который можно использовать в вышеперечисленных средах.
    В самом деле требование 1 без контейнеров выполнить сложно. Но контейнеры то разные в средах разработки: если C++ 3.1 то вообще не знаю, можно ли там со STL работать и использовать шаблон vector Если всё же с std::vector т.е конструкция типа vector <MyKlass> ekz
    То для класса MyKlass необходим конструктор без аргументов, что ограничивает разработчика.
    Аналогичная ситуация с CArray(MyClass,MyClass) (Visual C++) –тоже нужен пустой конструктор
    NET теперь предоставила контейнер ArrayList – но те же проблемы
    Ладно, проще уступить, сделал таки пустой конструктор. Далее 1 и то же объявление
    using namespace std;
    std::vector <book> B;
    в C++ Builder проходит без проблем, в NET компилятор говорит: error C2039: 'vector' : is not a member of 'std' несмотря на то что в подсказке на std:: есть vector ???
    Пришлось на NET обойтись вообще без контейнера, заменив его динамич массивом указателей:
    book ** B=new book*[n];
    При этом в цикле B=new book(tit,"Ivanov",i+100); - проходит
    Но для преобразования консольного ввода к типу char – ничего проще чем
    String *tt = Console::ReadLine(); //так как потоков cin>> в NET нет!!
    char* tit = (char*)(void*)Marshal::StringToHGlobalAnsi(tit);
    (согласитесь – нетривиально – откуда новичку вообще знать про Marshall – на сайтах по программированию типа Intuit.ru, Progs.biz.ru такие «тонкости» не публикуют – спасибо, сын помог)

    По поводу требования 2 – конечно методы могут возвращать массив значений по ссылке
    Но например при работе в C++ Builder удобен его специфический класс TStrings
    Т. Е типа TStrings *p=new TStringList(); p->Text=”Загол1\nЗагол2\nЗагол3\n”
    При этом возвращаемое методом значение этого типа одним махом можно отобразить например в ListBox,ComboBox: : ListBox1->Items=p
    Но если в классическом C++ то кроме char * ничего нет и при написании консольных приложений чаще всего такие методы должны выводить возвращаемое знач в виде массив(списка) на печать И, согласитесь неприятно при формировании char * вместо быстрого сцепления использ функц strcat а потом еще (если необходимо) разбирать этот выходной char * в реализации для выделения каждого элемента контейнера.
     
  5. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 10:54 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 10:54 )</span><!--QuoteEBegin-->То реализация данного класса существенно зависит от среды разработки
    [snapback]59918" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Реализация никак не может зависеть от среды, она зависит только от версии компилятора
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 10:54 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 10:54 )</span><!--QuoteEBegin-->То для класса MyKlass необходим конструктор без аргументов, что ограничивает разработчика.
    [snapback]59918" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Полный бред! Зачем в векторе хранить объект, если можно хранить указатель на него. И тогда плевать на конструкторы по умолчанию.

    Если честно прочел Ваш крик души и абсолютно запутался. Чего Вы хотите добиться? Чтобы Ваш код поддерживался разными компиляторами? Зачем такие сложности. Может стоит заново подумать над постановкой задачи?
     
  6. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    1)Я только хотел сказать ,что концепция ООП основанная на использовании в новых разработках ранее разработанных классов не совсем гладко проходит если разработанные классы планируется использовать в будущем в разных средах разработки. Возсожно в этом виноваты Borland и Microsoft наплодившие в своих средах только ими применяемые типы и контейнеры по сравнению с классическим ANSI C++
    2)Изыиняюсь за оговорку, говоря о "реализации класса" имел в виду не созданный объект класса, а сам процесс проектирования класса.
    3)По поводу хранения указателей на класс - принимаю и обдумаю.
    4) а как всё таки правильно в NET C++ работать со STL - почему ошибка ?
     
  7. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Так какие проблемы - пишите на стандартном С++, и не будет проблем с совместимостью. Предлагаемые расширения помогают постоянным разработчикам - но если вы пишите с VCL - глупо надеятся на то что этот код заработает на .NET. А если вы решите писать на .NET - не ждите что gcc с радостью его вам скомпилирует. Откуда вообще взялась цель использовать результат в разных средах?
     
  8. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 11:17 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 11:17 )</span><!--QuoteEBegin-->если разработанные классы планируется использовать в будущем в разных средах разработки
    [snapback]59922" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Если это изначально планируется, то нужно использовать средства оговоренные стандартом. Более того, не все компиляторы в полной мере поддерживают стандарт, но это уже из другой оперы
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 11:17 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 11:17 )</span><!--QuoteEBegin-->2)Изыиняюсь за оговорку, говоря о "реализации класса" имел в виду не созданный объект класса, а сам процесс проектирования класса.
    [snapback]59922" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Я тоже это имел в виду. Вы поймите, что компилятор и версия среды разработки это разные вещи, связанные только косвенно
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 11:17 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 11:17 )</span><!--QuoteEBegin-->3)По поводу хранения указателей на класс - принимаю и обдумаю.
    [snapback]59922" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Ну это общепринятая практика
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 11:17 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 11:17 )</span><!--QuoteEBegin-->а как всё таки правильно в NET C++ работать со STL
    [snapback]59922" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Что вы подразумеваете под NET C++? Вы пишете управляемое приложение или все-таки классическое неуправляемое. Во втором случае все должно быть в порядке, только оговорите версию среды разработки
     
  9. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    4) Я работаю на NET 2003 C++ (неуправляемое).Консольный вариант. Начало кода
    #include "stdafx.h"
    #include "book.h"
    #using <mscorlib.dll>
    #include <string.h>
    using namespace System;
    using namespace System::Runtime::InteropServices;
    using namespace std;

    int _tmain()
    { int n;//кол-во экз класса
    std::vector <book> B; //уже здесь компилятор спотыкается
    error C2039: 'vector' : is not a member of 'std'
     
  10. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 11:51 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 11:51 )</span><!--QuoteEBegin-->using namespace System;
    using namespace System::Runtime::InteropServices;
    [snapback]59931" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Если я не ошибаюсь, то эти пространства имен содержат управляемые расширения и их использовать нельзя. Хотя я могу и ошибаться.
    Далее если пишите using namespace std;, то зачем std::vector - масло масляное
     
  11. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    Так то оно так, только всё равно пишем ли Using namespace std
    вызываем ли vector<> или std: vector<> - результат один - не пропускает.
    System::Runtime::InteropServices; тут не причём - исключал его вместе с строчками соотв кода - результат 1 и то же
     
  12. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    На объявление Book хотелось бы взглянуть.
     
  13. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 12:02 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 12:02 )</span><!--QuoteEBegin-->System::Runtime::InteropServices; тут не причём - исключал его вместе с строчками соотв кода - результат 1 и то же
    [snapback]59936" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Ну на вектор это никак и не могло повлиять.
    Может добавить #include <vector>?
     
  14. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    Да, спасибо .Именно этого не хватало.
    Правильный минимум таков:
    #include <vector>
    using namespace std;
    ...
    vector <book *> //массив указателей на класс
    B; book b;
    .....
    b= book(tit,"Ivanov",i+100);
    B.push_back(&b);
    Получается с STL это удаётся.
    Для полноты счастья попробую с CArray под Visual C++

    vector <book *> B; book b; //извините в предыд ответе случайно произошел перенос
     
  15. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    Только что понял, что преждевременно сказал, что успех. Код выше, запихивает в вектор указатели на объект, а не сами объекты, при этом т.к сам объект меняет ссылку - то вектор содержит указатели не на все объекты - а лишь на последний созданный объект.
    Правильный код всё таки использует хранение в векторе самих объектов а не указателей
    book b;
    vector <book > B;

    b=book(tit,au,ns,jnr);
    B.push_back(b); // а не предыдущий вариант -проверял работает правильно.
    Так что тезис о хранении в векторе указателей на объекты а не сами объекты вызывает сомнение
     
  16. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--QuoteBegin-Е.Багоцкий+23:03:2007, 14:47 -->
    <span class="vbquote">(Е.Багоцкий @ 23:03:2007, 14:47 )</span><!--QuoteEBegin-->вектор содержит указатели не на все объекты - а лишь на последний созданный объект
    [snapback]59966" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Абсолютный бред! Все указатели хранятся там. Как то неудобно взрослого человека тыкать носом в книгу, но все же... С вектором возможно работать так же как и с массивом. Покажите код, который вызывает затруднение
     
  17. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    //C++ Builder
    using namespace std;
    lib_card c; vector <lib_card *> C;
    book b; vector <book *> B;
    void __fastcall TForm1::bOKClick(TObject *Sender)
    {
    AnsiString tit=en->Text; AnsiString au=ea->Text;
    int ns=StrToInt(ek->Text);
    int jnr= cj->ItemIndex;
    b=book(tit,au,ns,jnr);
    B.push_back(&b);
    pAdd->Hide();
    }

    TForm1::setBooks(int nj) //отображение книг заданного жанра
    { lb->Clear();
    for (int i=0;i<B.capacity();i++)
    {
    if (nj < 0) lb->Items->Add(B->show_bookStr());
    else if (B.show_janr()==nj) //здесь в цикле по i должны отображ названия разных книг !!!
    lb->Items->Add(B->show_bookStr()); //а отображаются – последней созданной книги !!!
    }
    }

    void __fastcall TForm1::cmbJChange(TObject *Sender)
    { int nj=cmbJ->ItemIndex;
    setBooks(nj);
    }
    При изменении всего лишь 3 операторов vector <book *> B; на vector <book > B;
    И B.push_back(&b); на B.push_back(b);
    И B->show_janr() на B.show_janr() получается всё верно - после прохода цикла по
    B.capasity() в списке отображаются разные книги, чего нет в предыдущ случае !!!
     
  18. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Потому и говорим в 2 голоса - читать и осмысливать страуструпа. Хотя после VB, верю, непросто :)
    B.push_back(new book(tit,au,ns,jnr));
     
  19. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Код (Text):
    void __fastcall TForm1::bOKClick(TObject *Sender)
    {
    ...
    book* pb = new book(tit,au,ns,jnr);
    B.push_back( pb );
    ...
    }
    В Вашем коде создан только один объект, он изменяется и указатель на него помещается в вектор. Естественно, что все объекты одинаковы
     
  20. eugira

    eugira Member

    Регистрация:
    2 фев 2007
    Сообщения:
    14
    Симпатии:
    0
    Да ,я это понял. Спасибо.
    Всё-таки интересно работать с классами, когда много экземпляров а не 1 -3 как в учебных примерах
    которыми нас пичкают на учебных сайтах.
     
Загрузка...
Похожие Темы - Массивы экземпляров класса
  1. Искушенный
    Ответов:
    0
    Просмотров:
    430
  2. Искушенный
    Ответов:
    1
    Просмотров:
    417
  3. Искушенный
    Ответов:
    1
    Просмотров:
    384
  4. Rpp
    Ответов:
    1
    Просмотров:
    809
  5. romanovbadboy2
    Ответов:
    0
    Просмотров:
    669

Поделиться этой страницей