C++/Cli и массивы

Retor

     Почему при объявлении многомерного массива его значения не инициализируются?

array<array<array<double>^>^>^ arr = gcnew array<array<array<double>^>^>(3);

Как его проинициализировать, кроме как обойти в цикле все его элементы? Методом Initialize что-то не выходит.

nvm77rus

какой-нибудь memset/ аналог паскалевского fillchar

Missi4ka

Не, мемсетить уж точно не надо. :)
А что ты, собственно, подразумевал под инициализацией? Если "внешний массив" содержит указатели (на "внутренние" массивы или на любые другие объекты - не важно то для этих указателей инициализация - это в лучшем случае зануление, конструкторы для обектов, адресуемых указателями, автоматически вызывться не будут. Если же "внутренние" массивы - это собственно экземпляры класса array, то для них инициализация по умолчанию - это создание пустых массивов. Просто в твоем сообщении неясно, что означают крышечки "^" :)

Retor

У меня есть массив arr, в котором прописаны все значения и масив qwer, который просто объявлен. Я хочу, скопировать все элементы массива arr в массив qwer. Если сделаю
так
 Array::Copy(arr, qwer, arr.Length); 

, не проинициализировав перед этим qwer, то компиилятор выдаст ошибку (что-то в духе nullReference а если проинициализирую - все будет ОК. Поэтому и возник вопрос.

karkar

Крышечки из Managed C++, как и gcnew, как я понял.

Missi4ka

сам класс Array - где его описание?

slonishka

в мсдне наверное каком-нибудь есть. вообще, жесть, конечно.
я сначала тоже написал что-то, а потом посмотрел, что managed и стер пост от греха подальше. =)

Retor

сам класс Array - где его описание?
В MSDN.

Dasar

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

array<double,3>^ arr = gcnew array<double,3>(10, 10, 3);
arr[5, 5, 1] = 5;

Werdna

Господи, каких же уродов пораждает планета Микрософт...
И ведь через 1 год он будет "профессионалом с годом опыта".
Совет чуваку: сделай что-то, чтобы не вызывать такую реакцию. Хотя бы тем, что не пиши на этом убогом микрософтовском языке. Есть ты не смог изучить нормальные плюсы, стоит подумать о смене профессии. Пока молодой...
Ну и как бы пойми, что изучать С++ с Микрософта — это путь явно не лучший.

agaaaa

Ха! А как по-твоему тогда сделать трёхмерный вектор на STL C++?

Olenenok

Убивать надо тех, кто использует трёхмерные векторы.

agaaaa

предложи замену

Olenenok

Для чего нужно использовать трёхмерные векторы? С какой целью?

agaaaa

Трёхмерные уровни в пошаговых играх например.

Olenenok

какой ужос, ради одной такой задачи можно с лёгкостью написать свою собственную обёртку над vector<vector<vector<double> > >, чтобы превратить её в настоящий трёхмерный массив. К тому же, мне кажется, что и это неправильный подход

Dasar

> какой ужос, ради одной такой задачи можно с лёгкостью написать свою собственную обёртку над vector<vector<vector<double> > >,
хмм. если уж делаешь велосипед, то делай его правильно.
обертку надо делать не поверх 3-х мерного jagged-массива, а поверх одномерного массива, чтобы память единным куском выделялась.

Dasar

Ну и как бы пойми, что изучать С++ с Микрософта — это путь явно не лучший.
если уж ты живешь в прошлом веке, то там живи, что на других наезжаешь?
MC++ по сравнению с родными C++ намного более удобный и разумный язык.
и если уж хочется выучить C++, то лучше сначала выучить именно MC++

slonishka


C++/CLI is a set of extensions to ISO C++ that provides an extremely complete "binding" of C++ to Microsoft's CLI (Common Language Infrastructure). It has been standardized by ECMA (ECMA-372). I am happy that it makes every feature of the CLI easily accessible from C++ and happy that C++/CLI is a far better language than its predecessor "Managed C++". However, I am less happy that C++/CLI achieves its goals by essentially augmenting C++ with a separate language feature for each feature of CLI (interfaces, properties, generics, pointers, inheritance, enumerations, and much, much more). This will be a major source of confusion (whatever anyone does or says). The wealth of new language facilities in C++/CLI compared to ISO Standard C++ tempts programmers to write non-portable code that (often invisibly) become intimately tied to Microsoft Windows. :FIREdevil:
век мекрософта как раз проходит. щас вроде в моде кроссплатформенность всякая. =)

Dasar

век мекрософта как раз проходит. щас вроде в моде кроссплатформенность всякая. =)
но уж C++ это точно не язык кроссплатформенности.
зы
если кроссплатформенность будет не только в моде, но и действительно будет необходима для решения реальных задач - значит микрософт будет кроссплатформенным.

Olenenok

я уже сообщал, что считаю использование трёхмерных массивов неправильным подходом?

Dasar

ты не сказал, что использовать вместо них при решение задач содержащих 3-х мерное пространство

slonishka

> если кроссплатформенность будет не только в моде, но и действительно будет необходима
> для решения реальных задач - значит микрософт будет кроссплатформенным.
что значит "кроссплатформенность необходима для решения реальных задач"?
если нужно написать охуенный медиаплеер — это реальная задача, для которой необходима кроссплатформенность?

Dasar

если нужно написать охуенный медиаплеер — это реальная задача, для которой необходима кроссплатформенность?
вот ты хочешь написать охуенный кроссплатформенный медиаплеер?
я нет. и думаю ты тоже нет. и почти все в этом форуме тоже не хотят писать охуенный медиаплеер.
поэтому это слабо похоже на реальную задачу.
зы
кстати C++ слабо помогает при написании кроссплатформенных охуенных медиаплееров

slonishka

то есть я понимаю, конечно, что можно бесконечно писать говнокод,
который будет использоваться внутри одной компании, и который никому не покажут,
но есть же и другие виды "реальных задач".
я просто не знаю, неужели настолько проще писать на этом непонятном CLI, когда есть обычный ISO C++.
или вообще C, который все знают.

slonishka

кстати C++ слабо помогает при написании кроссплатформенных охуенных медиаплееров
С++ хотя бы не мешает. в отличие от CLI.

Dasar

> С++ хотя бы не мешает. в отличие от CLI.
CLI переносится на любую платформу намного проще, чем C++.
единственная разница, что C++ уже лет 40, и для многих платформ C++ уже перенесли, а CLI - нет.

Dasar

> я просто не знаю, неужели настолько проще писать на этом непонятном CLI, когда есть обычный ISO C++.
почему ты считаешь, что есть "непонятный CLI" и есть "понятный C++"?
потому что ты пару лет назад выучил С++, но не учил Cli?
cli довольно логичный язык, и довольно успешно продолжает концепции заложенные страуструпом в C++.
например, я ни разу ни одной книжки/ни доки по CLI ни разу в глаза не видел, но при этом могу на нем довольно уверенно писать

slonishka

ну если перенос возможен без поддержки микрософт, я ничего против не имею. кому оно надо, тот пусть пишет.
но не факт, что это так. я не знаток CLI.
и возвращаясь к вопросу об изучении программирования вообще.
ты же видишь, к каким вопросам приводит вот такое вот изучение.
"почему у меня не инициализируется трехмерный массив?
пешу <array<array<blablabla<double>>> = microsoft_special_instruction(my_mega_pool) и нифига!
что делать, подскажите?"
имхо это жесть.

slonishka

я не уверен, мб для изучения CLI необходимо как минимум два монитора? =)
вообще, не читал, конечно, но если можно перенести под что угодно без участия микрософта, то я перестаю исходить говном. =)

Dasar

дык, CLI можно рассматривать как произвольную либу для C++, как например тот же boost/stl и т.д.
кстати вопросы "как мне проинициализировать std::vector" не менее редко появляются - даже в данном форуме.

Dasar

> но если можно перенести под что угодно без участия микрософта
зачем тебе microsoft? CLI - это ecma стандарт, бери да переводи, кто тебе мешает?

slonishka

> дык, CLI можно рассматривать как произвольную либу для C++, как например тот же boost/stl и т.д.
дык, тогда вроде полно фреймворков всяких. Poco там какой-то есть, Boost тот же, может еще какие-то, я не фанат. =)
> кстати вопросы как мне проинициализировать std::vector не менее редко появляются - даже в данном форуме.
ну да, просто на них ответы уже 40 лет прописаны (меньше, ага, не суть).
а в мсдне, судя по отзывам знакомых developers(tm много противоречивой информации, неадекватных ссылок и вообще говна.

agaaaa

ёклмн
а с чего ты взял, что автор не пишет обёртку вокруг сабжа?

slonishka

> зачем тебе microsoft? CLI - это ecma стандарт, бери да переводи, кто тебе мешает?
ну вот и славно. не буду изобретать велосипед в виде трехмерного вектора.
буду изобретать звездолет в виде реализации CLI.

agaaaa

> чтобы память единым куском выделялась
тогда понадобится больше операций, чтобы достучаться до конкретного элемента

agaaaa

Mono и Microsoft занимаются этим достаточно активно.
C# развивается сейчас гораздо быстрее C++. Будущий стандарт последнего местами идёт по уже протоптанной дорожке.

slonishka

тогда понадобится больше операций, чтобы достучаться до конкретного элемента
а по памяти типа мгновенно ходить можно?
все быстрые реализации матриц, выделяют память куском и это правильно.
вот я же говорю: изучение технологий(tm) приводит к пиздецовым результатам.

agaaaa

Умножения быстрее косвенных переходов?

slonishka

да пусть развивается, мне похуй. :(

Dasar

> Умножения быстрее косвенных переходов?
на современных процах - точно быстрее.

kokoc88

MC++ по сравнению с родными C++ намного более удобный и разумный язык.
Ужасное и грубое поделие с убогим синтаксисом. Причём, абсолютно бессмысленное и незижнеспособное. Если нужен этот самый "managed" - надо сразу писать на C#. Все managed фишки в С++ сами по себе смысла не имеют - либо они managed, либо родные. Например, конвертация указателей в managed код и обратно возможна только с помощью вызова дополнительных методов.

kokoc88

либо они managed, либо родные
Если говорить точнее, то выучив managed C++ получим стиль кодирования как на C#/Java, который совершенно неприменим для кодирования на C++.

Dasar

Если говорить точнее, то выучив managed C++ получим стиль кодирования как на C#/Java, который совершенно неприменим для кодирования на C++.
что в этом плохого?

kokoc88

что в этом плохого?
То, что нельзя сказать твоими словами:
если уж хочется выучить C++, то лучше сначала выучить именно MC++

Смысла учить MC++ нет, потому что лучше сразу учить C#. Я же написал, что стиль кодирования различается радикально, в случае MC++ ты не можешь научиться использовать все преимущества обычного C++. Да и сам язык просто притянут за уши, C# гораздо удобнее.

agaaaa

Это всё равно не отменяет того, что MC++ лучше выучить, чем C++
Короче, имхо, вы оба правы.

kokoc88

Это всё равно не отменяет того, что MC++ лучше выучить, чем C++
Как раз отменяет. Вместо MC++ надо сразу учить C#. Учить всё в одном не надо. Чего только стоит механизм контроля ресурсов: для managed классов придётся писать try/finally конструкции, в то время как для обычных C++ классов придётся использовать деструкторы. Дальнейший спор можно свести только к тому, что лучше учить C#/Java вместо С++, что опять же полный бред.

Dasar

Чего только стоит механизм контроля ресурсов: для managed классов придётся писать try/finally конструкции, в то время как для обычных C++ классов придётся использовать деструкторы
зачем писать через try/finally?
весь смысл C++/CLI, что даже для managed классов подерживается освобождение через деструктор.

kokoc88

весь смысл C++/CLI, что даже для managed классов подерживается освобождение через деструктор
Ничего там на самом деле не поддерживается. Тебе придётся везде пихать врапперы. Смысла в этом нет, как я уже сказал, лучше сразу учить C#. Потому что ты предалгаешь уже какую-то третью схему, где тебе руками придётся контролировать gc.

Dasar

> Тебе придётся везде пихать врапперы
еще раз спрашиваю кто тебе сказал такую дурость?
managed-класс можно как выделить на стеке (если не требуется передача его по gc-ссылке и он сам умрет при выходе из блока

StreamWriter writer("q.txt");
writer.WriteLine("f");

либо можно заюзать смарт-поинтер auto_gcroot<StreamWriter^> и опять же все само умрет при выходе из блока

auto_gcroot<StreamWriter^> writer = gcnew StreamWriter("q.txt");
writer->WriteLine("f");

зачем какие-то try/finally мне совсем не понятно.

kokoc88

еще раз спрашиваю кто тебе сказал такую дурость?
Любой хэлп по MC++. Везде пишется try/finally конструкция. Что, кстати, правильно. Если надо, приведу пример, почему правильно. Всё остальное что ты написал, я прекрасно понимаю и не спорю. Но, например подход с выделением класса на стеке, может привести к проблемам, если объект превратить в ссылку и оставить её где-нибудь. Опять же, эту проблему лучше решать через try/gcnew/finally. Приходим к тому, что лучше писать сразу на C#/Java.

Dasar

> если объект превратить в ссылку и оставить её где-нибудь
это нельзя сделать даже теоретически
> Опять же, эту проблему лучше решать через try/gcnew/finally
чем это лучше, чем smartpoint?
> Приходим к тому, что лучше писать сразу на C#/Java
в целом, согласен.
но C++/CLI более низкоуровневый язык, чем C#/Java. соответственно на C++/Cli можно сделать какие-то вещи, которые нельзя сделать на C#/Java.

kokoc88

Я думал, что unsafe C# вполне позволяет делать многие вещи, которые делаются на MC++... Впрочем, никогда этим не пользовался.

Dasar

Ну вот у меня как-то получается
приведи код

Dasar

Основной упор я делаю на то, что стили кодирования с и без GC кардинально различаются, и не стоит их перемешивать.
что есть gc, что нет gc - стиль кодирования один и тот же.
т.к. ресурсы никуда не девается, и эти ресурсы все равно надо явно освобождать, а gc позволяет лишь память не считать ресурсом.

kokoc88

приведи код
Я давно этим не занимался. :( Ну что-то типа этого:

ref class test { };

class test_holder
{
public:
test_holder(test^ ptest) : m_ptest(ptest) { }
gcroot<test^> m_ptest;
};
....
test stack;
pholder = new test_holder(%stack);

Dasar

> Я думал, что unsafe C# вполне позволяет делать многие вещи, которые делаются на MC++... Впрочем, никогда этим не пользовался.
писать managed код без gc на C++/CLI можно, а на C# нельзя.
зы
ты кстати уверен, что ты не путаешь MC++ с C++/CLI?

kokoc88

что есть gc, что нет gc - стиль кодирования один и тот же.
т.к. ресурсы никуда не девается, и эти ресурсы все равно надо явно освобождать, а gc позволяет лишь память не считать ресурсом
Ну здесь я с тобой не согласен. Обоснования уже много раз приводил. :) С GC кодирование будет опираться на try/finally, что, кстати, чаще ведёт к ошибкам. Без GC кодирование будет опираться на деструкторы. Конечно, это не единственная разница, просто самая очевидная.

kokoc88

ты кстати уверен, что ты не путаешь MC++ с C++/CLI?
Не уверен.

Dasar

С GC кодирование будет опираться на try/finally, что, кстати, чаще ведёт к ошибкам.
еще раз спрашиваю, почему в C# - обходятся без try/finally, а C++ должен использовать try/finally?
ps
ты кстати помнишь то, что auto_gcroot - автоматом вызывает Dispose при выходе из блока?
и что вот такое объявление:

ref class X
{
public: ~X{}
};

на самом деле неявно реализует Dispose

Dasar

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

kokoc88

еще раз спрашиваю, почему в C# - обходятся без try/finally, а C++ должен использовать try/finally
Вообще-то в C# без этого не обходятся. Если, конечно, не считать using великим достижением в этой области. :)
ты кстати помнишь то, что auto_gcroot - автоматом вызывает Dispose при выходе из блока

Помню. Но это не значит, что я не могу запихать хранимую там ссылку куда-то ещё. Например, вызвать метод, исходного кода которого у меня нет. Если бы мы программировали на C#/Java, то можно было бы об этом вообще не думать. Здесь же приходится следить за CG объектами практически так же, как следим за обычными C++ указателями. В таком случае, отпадает необходимость в GC.
Кроме того, мы-таки дошли до того, что на всё нужны врапперы, как я и написал выше.

kokoc88

идею понял, но у меня не получилось так сразу написать код, который бы выводил некорректный результат
Я могу тебе этот код дописать до некорректного результата. До использования disposed объекта - вообще влёгкую, ты и сам это можешь сделать. :smirk:
Дальше легко довести этот код до гремучей смеси, которая на чём-нибудь шлёпнется...

Dasar

До использования disposed объекта - вообще влёгкую, ты и сам это можешь сделать.
это можно сделать и в C#, и ничего в этом особо страшного нет.
меня больше интересовало, можно ли сделать, чтобы был проезд по памяти или нет.

Dasar

Вообще-то в C# без этого не обходятся. Если, конечно, не считать using великим достижением в этой области
не вижу разницы между using-ами в C# и деструкторами в C++.
и то и другое - позволяет сделать скобочное автоматическое освобождение ресурсов
> Кроме того, мы-таки дошли до того, что на всё нужны врапперы, как я и написал выше
smartpointer и wrapper - это одно и тоже в твоем понимании?

kokoc88

это можно сделать и в C#, и ничего в этом особо страшного нет.
меня больше интересовало, можно ли сделать, чтобы был проезд по памяти или нет.
Это в C# нет, а в смеси с сырой памятью C++ можно получить всё, что угодно. В моём примере сырой C++ код рассчитывает на то, что объектом занимается GC, откуда возникает ошибка. До сих пор не вижу ничего хорошего в MC++, чтобы рекомендовать его вместо C++...

kokoc88

не вижу разницы между using-ами в C# и деструкторами в C++.
и то и другое - позволяет сделать скобочное автоматическое освобождение ресурсов
Деструкторы удобнее, хотя бы тем, что их нельзя забыть. :) А вот using или try/finally - влёгкую.
smartpointer и wrapper - это одно и тоже в твоем понимании?
Ты пойми, в C# я напишу просто A a = new A а в MC++ мы уже дошли до необходимости либо заворачиваться во врапперы, либо использовать всё тот же try/finally. Причём мы так же дошли до того, что смесь двух подходов ведёт к проблемам.

Dasar

> Ты пойми, в C# я напишу просто A a = new A а в MC++ мы уже дошли до необходимости либо заворачиваться во врапперы, либо использовать всё тот же try/finally
не фига не понял.
если в C# - ты пишешь A a = new A;, то в C++/CLI ты тоже пишешь просто A^ a = gcnew A; - и никаких wrapper-ов.
если же ты пишешь в C#: using (A a = new A то в C++/Cli - ты пишешь auto_gcroot<A^> a = gcnew A и опять никаких wrapper-ов.
причем проблемы(поведение) будут одни и те же: что в C# если забыть using, что в C++/Cli - если забыть auto_gcroot

Dasar

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

bleyman

век мекрософта как раз проходит. щас вроде в моде кроссплатформенность всякая. =)
---
Поэтому silverlight кроссплатформенный и век микрософта никуда не проходит.

kokoc88

если же ты пишешь в C#: using (A a = new A то в C++/Cli - ты пишешь auto_gcroot<A^> a = gcnew A и опять никаких wrapper-ов
Я называю это враппингом. Просто в C# ты пишешь try/finally/using и это нормально для этого языка, в C++ ты всё время учишься работать с деструкторами. В MC++ ты пишешь какую-то смесь: то ты сам контролируешь GC, то используешь классический C++ стиль, то опираешься полностью на GC. Фактически, ты предлагаешь каким-то образом обучить человека сразу двум стилям кодирования. После этого он не сможет нормально писать ни на C#, ни на C++. Опять же, правил, которые надо соблюдать, для MC++ будет гораздо больше, чем отдельно для C# или C++, выше уже приведены примеры. Так и не понял, чем же лучше учить MC++ вместо C++

Werdna

Как бы тред почитал, даже минусовать не стал.
Как бы кому-то дано от Бога писать, кому-то яйца (тьфу, указатели) мешают. Всё нормально, профессия новая, через лет 20 всё устаканится.
Кто-то будет писать сложные вещи, кто-то — формы в сишарпе кодить. Есть же сейчас те, кто проектируют новые процессоры, а есть те, кто виндовсы по помам ходять инсталлировать. Через 20 лет разница будет ещё более заметной. :p

Dasar

Просто в C# ты пишешь try/finally/using и это нормально для этого языка, в C++ ты всё время учишься работать с деструкторами.
с таким же успехом можно сказать, что в C++ учишься работать с явной обработкой ошибкой - if(ошибка) то файл.закрыть и т.д.
причем аргументы будут теми же самыми: в половине книжек и исходников именно так делается работа, и нет никаких деструкторов.
что ты привезался к try/finally - это неправильный стиль программирования, зачем на нем фиксироваться?
такой же неправильный, как в C++ явно освобождать ресурсы без заворачивания в конструктор/деструктор.
> Фактически, ты предлагаешь каким-то образом обучить человека сразу двум стилям кодирования
правильный стиль один - ресурс должен освобождаться автоматом
про gc вообще думать не надо, т.к. еще раз повторяю, что gc лишь позволяет считать память не ресурсом.
писать на C++/Cli лучше тем, что не надо заморачиваться со всякими простыми объектами: коллекции, строки и т.д. - т.к. они опять же перестают быть ресурсами.
C++/Cli - managed, соответственно в большей степени устраняются ошибки, связанные с проездом по памяти, что очень важно при обучении.

kokoc88

с таким же успехом можно сказать, что в C++ учишься работать с явной обработкой ошибкой - if(ошибка) то файл.закрыть и т.д.
причем аргументы будут теми же самыми: в половине книжек и исходников именно так делается работа, и нет никаких деструкторов.
Разве ты сам не видишь разницу между using/IDisposable и деструкторами? Для меня это разный стиль кодирования. И я не считаю, что try/finally это неправильный стиль. Для C# он как раз может быть правильным, иногда просто быстрее написать try/finally, чем дописывать объект, который не поддерживает IDisposable. Кроме того, помимо освобождения ресурсов есть такая вещь, как поддержка целостности состояния какого-нибудь объекта. Я говорю о чём-то вроде void f { this.someVar = true; try { } finally { this.someVar = false; } }
писать на C++/Cli лучше тем, что не надо заморачиваться со всякими простыми объектами: коллекции, строки и т.д. - т.к. они опять же перестают быть ресурсами.
C++/Cli - managed, соответственно в большей степени устраняются ошибки, связанные с проездом по памяти, что очень важно при обучении

Если ты используешь managed классы, то, как уже ни раз говорилось в этой ветке, смысла писать именно на MC++ нет. Я делаю упор на то, что managed и unsafe код в MC++ отличаются как стилем кодирования, так и наличием большого количества подводных камней. И если уж говорить о преимуществах managed кода, то C# в этом случае будет более правильным выбором, т.к. на MC++ человек как следует не освоит ни того, ни другого.

Dasar

Для C# он как раз может быть правильным, иногда просто быстрее написать try/finally, чем дописывать объект, который не поддерживает IDisposable. Кроме того, помимо освобождения ресурсов есть такая вещь, как поддержка целостности состояния какого-нибудь объекта. Я говорю о чём-то вроде void f { this.someVar = true; try { } finally { this.someVar = false; } }
в C++ надо будет как-то писать по другому? без try/catch?

kokoc88

в C++ надо будет как-то писать по другому? без try/catch?
Конечно. :) Ты ведь не можешь из любой функции выходить через throw, а finally нету.

Dasar

> Конечно. Ты ведь не можешь из любой функции выходить через throw, а finally нету.
сколько ты знаешь функций, которые гарантированно не кидают исключений?

kokoc88

сколько ты знаешь функций, которые гарантированно не кидают исключений?
А кто сказал, что я не буду кидать исключений? Я буду их кидать, и у меня всё будет работать правильно. Но мы уже ушли от темы.

slonishka

Поэтому silverlight кроссплатформенный и век микрософта никуда не проходит.
ссылка в тему
Оставить комментарий
Имя или ник:
Комментарий: