Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/27: Рейтинг темы: голосов - 27, средняя оценка - 4.85
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65

Один и тот же код на С++ и С#, Шаблоны, отображение содержимого шаблонного класса

01.06.2012, 09:58. Показов 5131. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
написан на С++ шаблонный класс "List" созданный для создания списковой структуры внутри двоичного файла ([элемент][номер байта с которого следует читать следующий элемент(указатель)])
предусматривается работа с любыми данными для которых перегружены операции < > = cout
Для класса "List" определены операции ввода нового, удаления по номеру, сортировка, балансировка(Так как при удалении физически элемент не удаляется из двоичного файла, а переписываются указатели, спустя какое то время накапливаются элементы на которые нет ссылок но занимают память, функция балансировки переписывает файл уже без удаленных элементов)

следует переделать эту работу на С#, отображая на форме все данные о классе.

собственно мои вопросы:
1) отличие шаблонов в C++ и C#
2) если в С++ можно было перегрузить cout для корректного отображение элементов любого типа
то что следует сделать в С# c формами? Была идея отображать информацию в ListView, программно инициализируя новые колонки, но для этого надо знать количество полей класса и их имена. Есть ли в С# средства для подсчета количества полей класса?

Приветствуются любые советы ^^
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.06.2012, 09:58
Ответы с готовыми решениями:

Как корректно передать в метод шаблонного класса объект шаблонного класса в качестве параметра?
header.h template &lt;class T&gt; class MyVector { public: void swap(MyVector&lt;T&gt;Vector); } template &lt;class T&gt; void...

Почему перегруженные шаблоны функций должны возвращать один и тот же тип?
Так как я еще очень плохо знаю шаблоны и никак не могу понять. Почему у всех перегруженных шаблонных функций с одинаковыми именами так же...

Partial шаблонного класса (Весь основной код класса вынести в другой файл)
Здравствуйте, у меня есть главный класс, в котором содержится внутренний класс: public class DistributedArray&lt;T&gt; { //.... ...

20
 Аватар для Alex_Sabaka
638 / 499 / 77
Регистрация: 28.07.2010
Сообщений: 895
01.06.2012, 10:13
Цитата Сообщение от pinkiller Посмотреть сообщение
что следует сделать в С# c формами?
перегрузить метод object.ToString()
Цитата Сообщение от pinkiller Посмотреть сообщение
Есть ли в С# средства для подсчета количества полей класса?
есть, рефлексия называется
Цитата Сообщение от pinkiller Посмотреть сообщение
отличие шаблонов в C++ и C#
в C# шаблоны строже, вы не сможете так написать, к примеру:
C++
1
2
template<int y>
class xxx { }
В C# параметром шаблона может быть только тип, еще можно указать каким этот тип должен бить:
C#
1
2
3
4
class X<T> { } //просто генерик класс(в шарпе это так называется)
class X<T> where T: new() { } //передать можно только класс
class X<T> where T: struct{ } //только структура
class X<T> where T: IEnumerable { } //передать можно только объект унаследованый от IEnumerable
1
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 11:02  [ТС]
Только начал писать и сразу же возникли ошибки

Code
1
2
3
4
 class ListBin<T>:FileStream {
 
                  public ListBin():FileStream() { }
           }
почему так нельзя писать?
0
 Аватар для Alex_Sabaka
638 / 499 / 77
Регистрация: 28.07.2010
Сообщений: 895
01.06.2012, 11:14
потомучто для вызова бозового конструктора нужно так писать:
C#
1
2
public ListBin()
 : base() { }
1
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
01.06.2012, 11:17
Цитата Сообщение от pinkiller Посмотреть сообщение
почему так нельзя писать?
В C# нет множественного наследования, а значит не зачем писать точное имя родителя.
Для вызова родительского конструктора используется ключевое слово base
1
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 11:44  [ТС]
О спасибо большое
В другой программе на С# писал точное имя и все работало, странно ><

Добавлено через 22 минуты
Так, вот еще,
У меня есть класс наследник от FileStream
Я считать из потока информацию.
Для этого мне нужно создать объект класса BinaryReader
Code
1
BinaryReader BR = new BinaryReader(МойПоток);
Что мне нужно вставить на место "МойПоток"
Если в моем классе нет как такового поля "потока", я просто создаю поток при создание элемента класса наследника.
Или все таки завести поле? В С++ у меня был довольно красивый код без этого поля, хотелось бы как нибудь избежать создание поля типа FileStream если я и так наследую этот класс...
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
01.06.2012, 11:51
Передать this
0
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 11:55  [ТС]
О, ошибок не выдал
но так чисто по теории... через this передастся весь файл, да еще небось вместе с формой (её полями и тп) почему же конструктор сработает корректно?
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
01.06.2012, 12:04
this - это ссылка на объект. В данном случае сслыка на объект типа ListBin.
Но так как ListBin - наследник класса FileStream, то this будет являтьс ссылкой и на объект типа FileStream одновременно (а также ссылкой на каждого из родителей FileStream).
1
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 12:48  [ТС]
Далее...
В С++ была возможность в шаблонном классе сделать sizeof(T)
Как получить размер элемента класса в С#?
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
01.06.2012, 13:18
Эм, не знаю. А зачем это вам понадобилось?..
0
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 13:58  [ТС]
Принцип такой. Есть двоичный файл. В него пишется [элемент][адрес следующего элемента][элемент][адрес следующего элемента][элемент][адрес следующего элемента]
т.е чтобы считать элемент надо знать размер.
Программа работает с не динамическими типами, т.е int, char и тп. а так же с классами содержащими конкретное количество полей такого типа. т.е с классами размер элементов которых всегда одинаков

Добавлено через 34 минуты
Обратите внимание на темку пожалста ><
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
01.06.2012, 14:04
Никогда не писал объекты в файлы на C#, как-то все с БД.
Возможно, про что стоит почитать: сериализация объектов, fixed структуры, маршалинг.
0
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 16:28  [ТС]
Code
1
2
Type a = typeof(T);
int b =  Marshal.SizeOf(a);
Что такое маршалинг не знаю, но нашел вот такой способ... с матом перематом за 2 часа смог узнать что размер int32 - 4 ^^ Юхуууу

В смысле смог засунуть это в переменную...
........................................ ........................................ ......
имеется класс фиксированного размера.
Есть класс шаблон для которого пишется операция добавления элемента в двоичный файл.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Download(){
        int arrow, Num;
        Class a;
        
        Num=NumberALL();
        cout<<"What is the next item in the list?: ";   
        cin>>a;
        GoToEnd();
        arrow=(Num+1)*sizeof(int)+Num*sizeof(Class);
        write(reinterpret_cast<char*>(&arrow), sizeof(int));
        seekg(arrow, ios::beg);
        write(reinterpret_cast<char*>(&a),sizeof(Class));
        arrow=0;
        write(reinterpret_cast<char*>(&arrow), sizeof(int));
    };
В С++ write мог писать только const char* и для преобразования собственного класса была удобная функция
C++
1
reinterpret_cast<char*>(&a)
В С# метод Write перегружен, но только для стандартных структурных типов.

Есть ли у С# аналог reinterpret_cast<> ??
0
 Аватар для Konctantin
970 / 773 / 171
Регистрация: 12.04.2009
Сообщений: 1,700
01.06.2012, 19:57
запись структуры:
C#
1
2
3
4
5
6
7
8
9
10
public static void WriteStruct<T>(this BinaryWriter Writer, T obj) where T : struct
{
    int rawsize = Marshal.SizeOf(typeof(T));
    IntPtr buffer = Marshal.AllocHGlobal(rawsize);
    Marshal.StructureToPtr(obj, buffer, false);
    byte[] rawdatas = new byte[rawsize];
    Marshal.Copy(buffer, rawdatas, 0, rawsize);
    Marshal.FreeHGlobal(buffer);
    Writer.Write(rawdatas);
}
чтение структуры:
C#
1
2
3
4
5
6
7
8
public static T ReadStruct<T>(this BinaryReader reader) where T : struct
{
    byte[] rawData = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
    GCHandle handle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
    var returnObject = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
    handle.Free();
    return returnObject;
}
0
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 20:08  [ТС]
Konctantin, Можно хоть немного комментариев? Я не знаком и с половиной того что ты использовал ><
0
 Аватар для Alex_Sabaka
638 / 499 / 77
Регистрация: 28.07.2010
Сообщений: 895
01.06.2012, 20:59
Цитата Сообщение от pinkiller Посмотреть сообщение
Можно хоть немного комментариев? Я не знаком и с половиной того что ты использовал ><
Ну там кароче матан:
C#
1
2
3
4
5
6
7
8
9
10
public static void WriteStruct<T>(this BinaryWriter Writer, T obj) where T : struct
{
    int rawsize = Marshal.SizeOf(typeof(T)); //так как структуры не ссылочный тип данных, то можем узнать сколькож она в памяти занимает
    IntPtr buffer = Marshal.AllocHGlobal(rawsize); //тут выделяем память(сиплюплюшний malloc) под запись raw-данных структуры
    Marshal.StructureToPtr(obj, buffer, false); //копируем нашу структуру в только что выделенную память
    byte[] rawdatas = new byte[rawsize]; //создаем массив байтов, размером как наша структура
    Marshal.Copy(buffer, rawdatas, 0, rawsize); //и копируем участок памяти куда мы структуру положили в массив
    Marshal.FreeHGlobal(buffer); //освобождаем память
    Writer.Write(rawdatas); //и пишем в поток наш массив в котором уже лежат raw-данные структуры
}
Чтение структуры из потока происходит в точности наоборот.

PS Тут есть один нюанс, изза которого потом можете поиметь жестокий **** с дебаггером при отлове ошибок. Если мы объявим
такую структуру
C#
1
2
3
4
5
6
public struct foo
{
  public int x;
  public char y;
  public Tuple<int, int, int> lengths;
}
, то он не запишется в поток, т.к....
попробуйте сами догадаться
в структуре есть ссылочная переменная - lengths, т.к. Tuple<int, int, int> класс, а значение класса лежит не в стеке а в куче, а в стеке только ссылка на это значение, и в рантайме не возможно будет вычислить размер класса, т.к. рантайм не знает что там хранится, он только про ссылку знает. Вот поэтому при попытке выполнить ф-цию WriteStruct передав ей экземпляр структуры foo мы получим эксепшн
0
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 21:07  [ТС]
У получился вот такой вот код, он поооочти правильный... не хватает одного момента
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void Add(T item) 
        {
            BinaryWriter BW = new BinaryWriter(this);
            GoToLast();
            int arrow = CountWithFake()*(sizeof(int)+SizeOfT) + sizeof(int);
            BW.Write(arrow);
            Seek(0, SeekOrigin.End);
            Type a = item.GetType();
            T b =  (T)Convert.ChangeType(item, a);
            String fuckingC = "sd";
            Type str = fuckingC.GetType();
            String StrForWrite = (String)Convert.ChangeType(item, str);
            //Convert.ChangeType(item, a);
            BW.Write(StrForWrite);           
 
        }
Дело в том что String StrForWrite = (String)Convert.ChangeType(item, str); преобразует инт например в двубайтный вместо 4 байтного код, что печально. Но это ясно вообщем то почему, если передать одну цифру он ее представит в виде двубайтного юникодовского чара, и казалось бы выход очевиден, использовать конвертацию в Byte[] и писать, благо есть перегруженный метод у Write, но какогото *** Коневерт не может справится с преобразованим обычного инта в массив байтов.

Очень буду рад если кто нибудь не полениться и посмотрит мой код


Да кстати е**я с FuckingC - где лежит непонятно что вызвано неумением работать с классом Type, вот
0
 Аватар для Alex_Sabaka
638 / 499 / 77
Регистрация: 28.07.2010
Сообщений: 895
01.06.2012, 21:13
Для конвертации чего-либо в массив бай есть класс BitConverter
0
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 65
01.06.2012, 21:44  [ТС]
Alex Sabaka, А сам код можешь оценить? Начиная с 8ой строчки, все логично там? ><

Добавлено через 3 минуты
И да, в BitConverter все заточено под стандартные классы ><

Добавлено через 25 минут
Convert.ChangeType(item, a);

я не совсем понял, Тype a - типо того что мы преобразуем, или к чему?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.06.2012, 21:44
Помогаю со студенческими работами здесь

Вызов метода у шаблонного поля, шаблонного класса
Пытаюсь разобраться с шаблонами- задача создать шаблонный класс, у которого есть шаблонное поле. и затем вызывать метод у этого поля. ...

Дубликат класса. Widget1 и widget2 указывают на один и тот же объект
У меня есть абстрактный класс А, который является наследником QWidget, в своею очередь у меня есть n классов унаследованных от А. Также во...

Один и тот же код, но работает по разному
Один и тот же код но работает по разному. Если запускать код по шагам отрабатывает на все 100%, а если &quot;не по-шагам&quot;, то есть...

Один и тот же код выполняется по-разному
имеется код если его выполнять в visual studio 2010 то он выполняется по разному, иногда выводит flag = false flag = false а...

Один и тот же код по разному работает
Доброго времени суток, уважаемые товарищи! Решил написать код, заполняющий диагональ двумерной матрицы единицами, а остальное - нулями....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru