189 / 177 / 111
Регистрация: 22.06.2009
Сообщений: 533
1

В чем отличие ref class от value class, где какой следует использовать?

09.10.2014, 11:15. Показов 10899. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
САБЖ, мало по мало изучаю C++/CLI.. В голове каша, хотелось бы как то фундаментально осмыслить и запомнить в каких случаях нужно использовать ссылочный класс (ref class) и класс значений(я?) (value class). И почему...

П.С немного не там опубликовал, перенесите суда "Форум C++/CLI". Спасибо
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.10.2014, 11:15
Ответы с готовыми решениями:

Java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
Здравствуйте. При динамической загрузке кода столкнулся с такой ошибкой: ...

В чем отличие typename от class?
Зачем нужно typename В чем отличие от class ?

Разъясните код пжлст(выдает ошибку:cannot convert from 'class std::list<class c_bullet *,class std::allocator<class c_bullet *> >::iterator' to 'int')
Есть такие строки: std::list&lt;c_bullet*&gt; Bullets; ... for(auto i = Bullets.begin(); i !=...

Когда использовать [Class] и Hash[Class] ?
Начал изучать Java и почему-то не получается до сих пор понять, почему в некоторых примерах...

9
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
10.10.2014, 01:15 2
worldown, посмотрите этот топик:
Основные отличия C# от C++ CLI
даже если Вы не знакомы с C#. Отличия ссылочных типов от типов значений хорошо описаны именно в литературе по C#, которой очень много, в отличие от C++/CLI.
Кратко говоря, это два рода управляемых типов, которые по разному наследуют от общего родители System.Object.
Ссылка это имя, которое ссылается на память. Но в отличие от ссылок С++, она может быть объявлена без инициализации и это роднит её с указателем С++.
Имя переменной типа значения ведёт себя подобно имени стековой переменной. Совершенно ясно, что у типов значений и ссылочных, разный синтаксис, в частности: объявления, определения и разная семантика поведения, в частности: копирования, присваивания, сравнения, передачи в функцию в качестве аргумента. Писать обо всём этом просто неподъёмно, поэтому поищите и почитайте.
Нужно сказать, что управляемые строки String^ это ссылочные типы, но с семантикой класса значений при передаче в функцию. Важно ещё то, что строка это внутренне не изменяемый объект, то есть когда Вы изменяете строку, она пересоздаётся и ссылка изменяет значение.
К типам значений относятся простые встроенные типы и структуры. Они копируются сравниваются и передаются по значению и это не должно вызвать проблем, так как семантически сходно с С++. Для быстрых операций с большим объёмом простых данных или многократно повторяющихся операций с небольшим объёмом, быстрее использовать типы значений. Память выделяется и освобождается механизмом стека.
К ссылкам относятся имена экземпляров классов. Экземпляры создаются только в управляемой куче. Память выделяется и освобождается cборщиком мусора. Для того чтобы связать имя с объектом, нужно или приравнять другой инициализированной ссылке или создать объект в куче явно при помощи оператора-функции gcnew.
При копировании и сравнении копируются и сравниваются ссылки. Это значит, в частности, что две ссылки указывающие на один объект равны, а две ссылки указывающие на два совершенно идентичных объекта (при почленном сравнении), но расположенных в разных участках памяти, не равны. И тут ссылки более похожи на указатели. Поэтому их иногда называют управляемый указатель/дескриптор. Еще более роднит доступ к членом с использованием оператора ->.
Для того чтобы переопределить семантику копирования и сравнения, нужно унаследовать от интерфейсов IComparable, IClonable и определить виртуальные методы которые это будут делать самостоятельно.
В функции,экземпляры ссылочного типа передаются по ссылке.
Лучше всего почитайте об этом.
2
189 / 177 / 111
Регистрация: 22.06.2009
Сообщений: 533
10.10.2014, 11:29  [ТС] 3
IGPIGP, Спасибо. Так по порядку :
Цитата Сообщение от IGPIGP Посмотреть сообщение
Нужно сказать, что управляемые строки String^ это ссылочные типы, но с семантикой класса значений при передаче в функцию.
простите за безграмотность, не могу понять мысль. Стопорит от слова "семантика" (википедил не дошло)

Цитата Сообщение от IGPIGP Посмотреть сообщение
При копировании и сравнении копируются и сравниваются ссылки. Это значит, в частности, что две ссылки указывающие на один объект равны, а две ссылки указывающие на два совершенно идентичных объекта (при почленном сравнении), но расположенных в разных участках памяти, не равны.
А можно простой пример.. т.к лучше один раз увидеть чем 100 раз прочесть

Цитата Сообщение от IGPIGP Посмотреть сообщение
Для того чтобы переопределить семантику копирования и сравнения, нужно унаследовать от интерфейсов IComparable, IClonable и определить виртуальные методы которые это будут делать самостоятельно.
как для ссылочных типов так и для типов значения . Ризницы нет ?? Например:
C++
1
2
3
4
5
6
7
8
/*ref || value */ class FOO
{
//...
    public:
        virtual String^ ToString() override {
            //...
        }
}
В общем как я понял:
1) Что бы создать объект класса через отслеживаемый дескриптор , он же динамический объект он же в ISO/IEC аналог указателя. Нужно:
C++
1
2
3
ref class FOO {....}; //create ref class
FOO ^obj1 = gcnew FOO; //create an object "obj1" of class "FOO"
FOO obj2; //it does not work, only works with a value class
Но не понял главное, где нужно использовать стековый класс значения, а где ссылочный.. И почему они сразу не были объедены в один, зачем вся эта двойная работа??

В том то и дело, что читаю, читаю... и от этого только какая то каша без комьев ..
0
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,237
10.10.2014, 11:48 4
Цитата Сообщение от worldown Посмотреть сообщение
простите за безграмотность, не могу понять мысль.
Набросал пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using namespace System;
void func_test(String^ s);
int main()
{
            
    String^ str="key";
    func_test(str);     
    Console::WriteLine(str);    
    Console::ReadLine();
    return 0;
}
void func_test(String^ s)
    {
    s="текст";
    }
как видите,если бы String был "хорошим" ссылочным типом,строка в функции должна была изменится.А раз она не изменилось,то семантически ведет себя как значимый тип.

Цитата Сообщение от worldown Посмотреть сообщение
Но не понял главное, где нужно использовать стековый класс значения, а где ссылочный..
Если я правильно помню,то у значимых типов нет свойств и они имеют фиксированный размер.
Если пишите класс, делайте его ref, если хотите сделать его значимым - пишите struct.


worldown, по какой книге изучаете этот язык и с чем связан ваш выбор?

Добавлено через 7 минут
Разница между value class и value struct только в модификаторе доступа по умолчанию,в классах private,в структурах - public.(Это применимо и для ссылочных типов,так что пользуйтесь,тем что больше нравится).
1
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
10.10.2014, 13:29 5
Цитата Сообщение от worldown Посмотреть сообщение
Но не понял главное, где нужно использовать стековый класс значения, а где ссылочный..
Дык... Если Вы не хотите связываться с гэрбэдж-коллектор и задача это позволяет, то конечно всё можно сделать на стеке. Раскидать цепочку байт на чет/нечет например. Если цепочка в мегамногобайтj или таких цепочек много и делать нужно часто, то использовать ссылки, - чистое безумие. Нужно помнить, только, что код должен избегать упаковки/распаковки везде где это можно. В частности не стоит передавать типы значений в функции ожидающие Object и пр. Это отдельная тема и если не сталкивались, - почитайте обязательно.
Но сложные структуры данных не нужно пытаться создавать как структуры значений. Более того, если Вы используете классы NET то Вам и не удастся, это сделать, потому что value types не могут содержать ref, а если не используете, то зачем Вам вообще С++/CLI?
Ссылочные типы позволяют делать то, чего не позволяет STL/C++. Вы можете делать быстро и не занимая кучу памяти, практически всё, что требуется, для обработки информации. Оперируя единожды созданным набором объектов, можно создавать кучу наборов из них тратя память только на новые ссылки.
В С++ нельзя создать массив ссылок. И понятно почему, - ссылка объявляется и инициализируется одновременно, а массив, сначала выделяет память под умолчательные объекты, а потом использует копирование. Кроме того, даже на примере создания, видно сколько лишней работы. И при использовании moove-семантики всё равно время тратится. Я не хочу холивара и прошу плюсовиков, сдержаться. Сам лично, люблю С++/native и... други я с Вами и NOPASARAN.
Ещё одно. Управляемые типы диктуются системой. Их свойства не так прозрачны как свойства простых указателей, но это как раз прозрачно. Нельзя получить адрес, который нет смысла использовать, потому что это информация о том, где находился объект в момент его определения. С адресной арифметикой, и сравнением та же причина.
1
189 / 177 / 111
Регистрация: 22.06.2009
Сообщений: 533
10.10.2014, 15:30  [ТС] 6
S_el
Т.е объект класса String^ переопределить через функцию ни как не получится?
Цитата Сообщение от S_el Посмотреть сообщение
Если я правильно помню, то у значимых типов нет свойств и они имеют фиксированный размер.
Хм. В книге говорится: "Свойство (property) — это член либо ссылочного класса, либо класса значения"
или под св-свами Вы имеете ввиду что то другое ??
Цитата Сообщение от S_el Посмотреть сообщение
Если пишите класс, делайте его ref, если хотите сделать его значимым - пишите struct.
тогда это будет "стоковая"(ISO/IEC) C++ структура? Как я понял опять таки из книги что и структуру можно определить с помощью ref || value , да вообще что структура что класс это одно и то же, разница лишь в видимости по дефолту (public || private)
Цитата Сообщение от S_el Посмотреть сообщение
по какой книге изучаете этот язык и с чем связан ваш выбор?
Книга "Айвор Хортон - Visual C++ 2010. Полный курс - 2011" 7-я глава.
Выбор определила книга =)

Добавлено через 53 минуты
IGPIGP,
Из Вашего поста я понял следующее:
Если класс || структура выходит довольно таки сложной, нужно использовать ref , плюс его в том что будут доступны всякие вкусности .Net, которые облегчают труд разработчика и не загружает память. Так ?

Цитата Сообщение от IGPIGP Посмотреть сообщение
Но сложные структуры данных не нужно пытаться создавать как структуры значений. Более того, если Вы используете классы NET то Вам и не удастся, это сделать, потому что value types не могут содержать ref
зачем тогда value class в среде .Net, если сама же среда .Net этому классу что то запрещает ??
Можно пример.. ну не могу я догнать смысл мысли о смысле =(


Не по теме:

В общем, чувствую что мне пока рановато задавать такие не скромные вопросы.
Боюсь голова лопнет.. хотелось бы какого то порядку на пальцах, без сложных терминов..
и по полочкам.. Выходит же "чем дальше в лес тем больше дров"...

0
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,237
10.10.2014, 15:57 7
Цитата Сообщение от worldown Посмотреть сообщение
Книга "Айвор Хортон - Visual C++ 2010. Полный курс - 2011" 7-я глава.
Выбор определила книга =)
У меня эта книга тоже есть,насколько я знаю единственная на русском по C++/CLI

Цитата Сообщение от worldown Посмотреть сообщение
В книге говорится: "Свойство (property) — это член либо ссылочного класса, либо класса значения"
или под св-свами вы имеете ввиду что то другое
Член класса либо структуры это поле.А свойство это замаскированная под поле функция.
А про то,что свойства могут быть у классов-значений,я не знал.

Цитата Сообщение от worldown Посмотреть сообщение
Т.е объект класса String^ переопределить через функцию ни как не получится?
Получится,если передавать по явной ссылке:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using namespace System;
void func_test(String^ s);
void func_test2(String^ %s);
int main()
{        
    String^ str="key";
    func_test(str); 
    Console::WriteLine(str); 
    func_test2(str);
    Console::WriteLine(str);    
    Console::ReadLine();
    return 0;
}
void func_test(String^ s)
    {
    s="текст";
    }
void func_test2(String^ %s)
    {
    s="текст";
    }
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я не хочу холивара и прошу плюсовиков, сдержаться.
Настоящие плюсовики этот раздел не посещают

Добавлено через 4 минуты
Цитата Сообщение от worldown Посмотреть сообщение
Если класс || структура выходит довольно таки сложной, нужно использовать ref , плюс его в том что будут доступны всякие вкусности .Net, которые облегчают труд разработчика и не загружает память.
Правильно.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Более того, если Вы используете классы NET то Вам и не удастся, это сделать, потому что value types не могут содержать ref, а если не используете, то зачем Вам вообще С++/CLI?
Тоже попрошу пример.

Добавлено через 1 минуту
Цитата Сообщение от worldown Посмотреть сообщение
В общем, чувствую что мне пока рановато задавать такие не скромные вопросы.
Боюсь голова лопнет.. хотелось бы какого то порядку на пальцах, без сложных терминов..
и по полочкам..
Такие вещи узнать намного проще,когда столкнешься на практике.Можно программировать и без всякого углубления в тонкости определенного ЯП.
2
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
10.10.2014, 17:49 8
worldown, я отвечу на этот пост, так как ответы S_el, вполне удовлетворительны:
Цитата Сообщение от worldown Посмотреть сообщение
Из Вашего поста я понял следующее:
Если класс || структура выходит довольно таки сложной, нужно использовать ref , плюс его в том что будут доступны всякие вкусности .Net, которые облегчают труд разработчика и не загружает память. Так ?
Отчасти да. Ссылки имеет смысл создавать не только если они будут содержать ссылки на классы. Если у Вас тяжеловесные структуры значений с которыми придётся работать выходя из области, где они создаются, да ещё во многих контекстах, то смысл в использовании ссылок прямой и с использованием NET и классов как таковых не связан. Он тот же, что и в С++. Просто для передачи в качестве возвращаемого значения (с целью модификации) достаточно и передачи значения по ссылке. Об этом S_el сказал в примере со строкой String.
Цитата Сообщение от S_el Посмотреть сообщение
Тоже попрошу пример.
Пример чего?
Цитата Сообщение от S_el Посмотреть сообщение
Настоящие плюсовики этот раздел не посещают
Побойтесь бога.
0
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,237
10.10.2014, 18:21 9
Цитата Сообщение от IGPIGP Посмотреть сообщение
Пример чего?
Цитата Сообщение от IGPIGP
Но сложные структуры данных не нужно пытаться создавать как структуры значений. Более того, если Вы используете классы NET то Вам и не удастся, это сделать, потому что value types не могут содержать ref
Пример поясняющий запрет ref в value types.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Побойтесь бога
Ошибку понял
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
10.10.2014, 19:32 10
Цитата Сообщение от S_el Посмотреть сообщение
Пример поясняющий запрет ref в value types.
Вот с попыткой объявления дескриптора String^ на тип System.String :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
using namespace System;
 
namespace Value_tyies_vs_refs {
 
    public struct Val_struct{
String^ str;
 
    };
 
    public ref class Class1
    {
        // TODO: здесь следует добавить свои методы для этого класса.
    };
}
Диагностическое сообщение:
Цитата Сообщение от Compiller
Ошибка 1 error C3265: нельзя объявлять управляемый 'str' в неуправляемом 'Value_tyies_vs_refs::Val_struct' c:\users\ig\documents\visual studio 2008\projects\value_tyies_vs_refs\value_tyies_vs_refs\Value_tyies_vs_refs.h 10 Value_tyies_vs_refs
Как говорил известный партруководитель из к/ф "Кавказская пленница", - "Хулиганка! Ничего же не сделал, - слюшай! Только вошёл!"
А что, в действительности, непонятно в том, что я написал о типах значений?
Ну читаете Вы данные из файла, допустим. Потоки - ссылочные типы и чтение идет в буфер располагаемый в куче. Потом кусочкамипорциями через типы значения выбираете и разбираете в стеке. Зачем там ссылки?
1
10.10.2014, 19:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.10.2014, 19:32
Помогаю со студенческими работами здесь

Подскажите где можно использовать class Stack
Изучил class Stack а где его применять не знаю.

В чем разница между ID и Class и что лучшие использовать?
Добрый день не так давно начал изучать web, и у меня возникло пару вопросов 1) в чем разница между...

Что где использовать? Где ID, где class?
Здравствуйте. Всегда использовал в &lt;head&gt; &lt;body&gt; ID, а в остальных местах class, но после...

bad class file: C:Program FilesJavajre1.5.0_02lib t.jar(java/lang/Object.class) class file has wrong version 49.0, should be 48.0
написал тестовый td_jsp.jsp фаил -&gt;&gt; &lt;html&gt; &lt;head&gt;&lt;title&gt;JSP test&lt;/title&gt;&lt;/head&gt; ...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru