Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Реализация С# - конструкции в С++ 
V
    Опции темы
ioManip
Дата 12.11.2014, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 12.8.2011
Где: Благовещенск

Репутация: нет
Всего: нет



Привет. Есть такой вот кусок кода
Код

struct Element
{
     public int Value { get; set; }
}

И к примеру его применение
Код

for (i = 0; i < n; i++)
{
      for (j = 0; j < m; j++)
      {
           C[i, j].Value = Convert.ToInt32(Console.ReadLine());
       }
}


А как будет выглядеть,  такая же реализация на С++ ? Мне просто не совсем понятно, Value - это как метод? а set get ?

Это сообщение отредактировал(а) ioManip - 12.11.2014, 13:03
--------------------
Мечты не работают, пока ты не работаешь! 
PM MAIL Skype   Вверх
Guinness
Дата 12.11.2014, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: нет
Всего: 10



Цитата(ioManip @  12.11.2014,  14:01 Найти цитируемый пост)
А как будет выглядеть,  такая же реализация на С++ ?

Как таковых свойств в языке нет. Можно, например, использовать функции и возвращать из них ссылку или указатель.
Код

class A
{
public:
    int& Value() {return m_value;}
private:
    int m_value;
};

Можно просто объявить Value как public переменную класса:
Код

class A
{
public:
    int Value;
};

Но это рабочие случаи только если get и set - public. Полного аналога в языке нет. Можно придумать свой класс property, который будет выполнять похожую функциональность. Думаю в интернете должны были найтись умельцы, попытавшиеся реализовать подобное.

Это сообщение отредактировал(а) Guinness - 12.11.2014, 13:27
PM MAIL   Вверх
Ihost
Дата 12.11.2014, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 14.9.2012

Репутация: нет
Всего: нет



Отчего же? Если речь идет о языке C++, то возможность реализовать свойтсва с getter/setter-ами вполне себе существует, и основана на форсированном преобразовании типа в нестатическом перегруженном операторе присваивания
Конкретная реализация

Если речь идет о VC++, то там есть более элегантное решение - констуркция __declspec property
PM MAIL   Вверх
Guinness
Дата 12.11.2014, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: нет
Всего: 10



Цитата(Ihost @  12.11.2014,  14:44 Найти цитируемый пост)
Отчего же?

Цитата(Guinness @  12.11.2014,  14:25 Найти цитируемый пост)
Полного аналога в языке нет.

А про реализацию класса я говорил:
Цитата(Guinness @  12.11.2014,  14:25 Найти цитируемый пост)
Можно придумать свой класс property, который будет выполнять похожую функциональность. Думаю в интернете должны были найтись умельцы, попытавшиеся реализовать подобное.


Цитата(Ihost @  12.11.2014,  14:44 Найти цитируемый пост)
Если речь идет о VC++, то там есть более элегантное решение - констуркция __declspec 
property 

Про это не знал, однако,  это всё равно не отменяет того факта, что свойств в языке нет.
PM MAIL   Вверх
Ihost
  Дата 12.11.2014, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 14.9.2012

Репутация: нет
Всего: нет



Цитата(Guinness @  12.11.2014,  13:52 Найти цитируемый пост)
А про реализацию класса я говорил
Да говорили и возможно подразумевали это, но в конкретном Вашем примере предполагался простой класс с двумя функциями для получения и записи свойства - в то время как в примере по ссылке *нет* необходимости вызывать какие-то функции, и со свойством можно работать именно как с публичной переменной, в стиле C#
Код
 Myobj.Value() = x;  x= Myobj.Value(); // Ваш пример
Myobj.Value = x;  x= Myobj.Value; // Пример по ссылке

Учитывая что метод getter/setter-а  вызывается полностью автоматически, и внешне такое свойство мало отличимо от настоящего, то в принципе можно сказать, что реализация свойств в языке C++ есть, хотя и не прямая конечно

Это сообщение отредактировал(а) Ihost - 12.11.2014, 14:06
PM MAIL   Вверх
ioManip
Дата 12.11.2014, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 12.8.2011
Где: Благовещенск

Репутация: нет
Всего: нет



Цитата(Guinness @  12.11.2014,  13:25 Найти цитируемый пост)
Можно, например, использовать функции и возвращать из них ссылку или указатель.

Поправьте, если не так. То есть при такой записи
Код

class A
{
public:
    int& Value() {return m_value;}
private:
    int m_value;
};

и таком применении
Код

C[i, j].Value

Я буду получать значения, которые записаны в индексах i и j ?
--------------------
Мечты не работают, пока ты не работаешь! 
PM MAIL Skype   Вверх
Guinness
Дата 12.11.2014, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: нет
Всего: 10



Цитата(ioManip @  12.11.2014,  15:39 Найти цитируемый пост)

Я буду получать значения, которые записаны в индексах i и j ? 

Нет, Вам нужно добавить скобочки, чтобы работало. Чтобы было так, как Вы хотите, либо используйте предложенные варианты Ihost`ом, либо public переменная. Ещё можно, конечно, использовать managed C++, но, имхо, лучше не стоит.
PM MAIL   Вверх
ioManip
Дата 12.11.2014, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 12.8.2011
Где: Благовещенск

Репутация: нет
Всего: нет



Хорошо, спасибо!
--------------------
Мечты не работают, пока ты не работаешь! 
PM MAIL Skype   Вверх
Lukkoye
Дата 12.11.2014, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: 1
Всего: 1



Цитата(Ihost @  12.11.2014,  14:02 Найти цитируемый пост)
Учитывая что метод getter/setter-а  вызывается полностью автоматически, и внешне такое свойство мало отличимо от настоящего, то в принципе можно сказать, что реализация свойств в языке C++ есть, хотя и не прямая конечно


Если не обращать внимания, что нативной поддержки не существует.
А любые велосипеды - весьма весьма ограниченные костыли.

Без нативной поддержки приходится в ручную писать дополнительный код. И Код усложняется. Заметьте - на ровном месте.
Кроме того, костыльные велосипеды не способны покрыть всю возможную область применения, и охватывают лишь частные случаи:

Пример из указанной выше ссылки:
Код

operator ValueType()


Возвращает по значению, и только для неконстантных объектов.

Попытка сделать универсально провалится. Объяснять почему сейчас не стану - кто пробовал, тот знает. 
Там вылезет 100500 всевозможных нюансов в самых разных случаях.
Сложность конструкции будет только расти. И не избавит пользователя от необходимости писать дополнительный код: в ручную чего то там поднастраивать.


В этой ситуации проще написать простой и понятный даже новичку геттер/сеттер.
Чем геммороится с шаблонами, которые не избавят от необходимости в ручную писать код, а только все усложнят.
Собственно, поэтому и не прижились проперти на плюсах. 
Игра не стоит свеч.









PM MAIL   Вверх
Ihost
Дата 13.11.2014, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 14.9.2012

Репутация: нет
Всего: нет



Цитата(Lukkoye @  12.11.2014,  21:55 Найти цитируемый пост)
Возвращает по значению, и только для неконстантных объектов
Так это же пример самой простой реализации, если нужен возврат по ссылке - пожалуйста, можно сделать такие исправления
Код

void getter(ValueType& (Container::*pGet)())
{
  if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
    LGet = pGet;
  else
    LGet = NULL;
}
operator ValueType&()
{
    assert(m_cObject != NULL);
    assert(LGet != NULL);
    return (m_cObject->*LGet)();
}
ValueType& (Container::*LGet)();

Прекрасно используется следующим образом, в первом случае значение копируется надлежащим образом, а во втором - получается по ссылке; для запрета получения объекта по ссылке getter-функция может форсированно создавать копию объекта:
Код

PropTest test;
    test.Count = 10;    //-- call the set method --
    int i= test.Count;
    i = 20; // i==20; text.mCount ==10
    int& j= test.Count;
    j = 20; // j == text.mCount == 20

Если использовать диалект C++11, то можно еще больше усовершенствовать код с помощью конструкция перемещения для неконстантных rvalue-ссылок


В общем непонятно, в чем вообще заключается Ваша позиция? Если уж на то дело пошло, getter-ов и setter-ов нет вообще ни в каком языке - в конечном счете они превращаются в нативный или байт-код в зависимости от целевой используемой технологии
В языке C# эти элементы- считайте обертки для обычных функций, и все, и более того в C# не удастся передать такую штуку по ссылке, ибо ref/out доступны только в функциях
Так что реализация в C++ даже более мощная, чем натуралтная поддержка в некоторых другиях языках

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




PM MAIL   Вверх
xvr
Дата 13.11.2014, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Ihost @  13.11.2014,  14:12 Найти цитируемый пост)
Прекрасно используется следующим образом, в первом случае значение копируется надлежащим образом, а во втором - получается по ссылке; 

Попробуйте сделать так -
Код

PropTest test;
    test.Count = 10;
    printf("%d",test);
и поймете, чем проперть в С++ отличается от проперти там, где она реализованна на уровне языка   smile 

PM MAIL   Вверх
Ihost
Дата 13.11.2014, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 14.9.2012

Репутация: нет
Всего: нет



Цитата(xvr @  13.11.2014,  14:43 Найти цитируемый пост)
Попробуйте сделать так -
и поймете, чем проперть в С++ отличается от проперти там, где она реализованна на уровне язы

Если учитывать что printf- это не совсем типичная для языка C++-функция, ибо она принимает нетипизированные аргументы, то действительно есть небольшие аспекты, решаемые передачей строгого типа
Конструкция printf("%d",test); вообще работает только потому, что разрешен тривиальный копирующий конструктор- немного модифицировать класс, чтобы он перестал быть POD-типом
error: cannot pass objects of non-trivially-copyable type 'class PropTest' through '...'       printf("%d \n", test);

Если выводить даше шаблонными функциями, проблемы не возникает
Код

  property<PropTest,int,READ_WRITE> Count;
  property<PropTest,float,READ_WRITE> Ttt;

Код

    PropTest test;
    test.Count = 10;
    test.Ttt = 20.5;
    std::cout << test.Count << std::endl;
    std::cout << test.Ttt << std::endl;

PM MAIL   Вверх
xvr
Дата 13.11.2014, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Ihost @  13.11.2014,  15:24 Найти цитируемый пост)
Если учитывать что printf- это не совсем типичная для языка C++-функция, ибо она принимает нетипизированные аргументы, то действительно есть небольшие аспекты

Ну есть еще несколько конструкций, где будут проблемы. Ну например абсолютно С++ конструкция -
Код

template<class Type>
Type min(Type v1, Type v2)
{
 return (v1<v2) ? v1 : v2;
}

class Prop {
public:
 operator int() {return 1;}
};

int test()
{
 Prop p;
 return min(1,p);
}

Ошибка при компиляции:
Цитата

>g++ -c t.cc

t.cc: In function 'int test()':
t.cc:15:16: error: no matching function for call to 'min(int, Prop&)'
  return min(1,p);
                ^
t.cc:15:16: note: candidate is:
t.cc:2:6: note: template<class Type> Type min(Type, Type)
 Type min(Type v1, Type v2)
      ^
t.cc:2:6: note:   template argument deduction/substitution failed:
t.cc:15:16: note:   deduced conflicting types for parameter 'Type' ('int' and 'Prop')
  return min(1,p);
                ^


PM MAIL   Вверх
Lukkoye
Дата 13.11.2014, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: 1
Всего: 1



Цитата(Ihost @  13.11.2014,  14:12 Найти цитируемый пост)
Так это же пример самой простой реализации, если нужен возврат по ссылке - пожалуйста, можно сделать такие исправления


А потом ещё и ещё исправлений! Нужно больше исправлений, что бы выкрутиться из всех возможных ситуаций:

Это - только верхушка айсберга.
Код

some& obj = agregat.value; //должна вернуться не константная ссылка
const some& obj = agregat.value; //должна вернуться константная ссылка

some obj = agregat.value; //должна вернуться константная ссылка
//(для компилятора gcc добиться такого поведения невозможно)


Дальше хуже - великое множество ситуаций на шаблонах.


Проперти на плюсах  не дают никаких преимуществ, абсолютно ничего не привносят такого, чего нельзя было бы сделать  при помощи простых и всем понятных сеттеров/геттеров.

А сложность (в первую очередь пользовательского кода, про инструментальный я вообще молчу, там термоядерная магия на шаблонах все равно не справится со всеми случаями) - увеличивают неимоверно.

Что делает их существование на этом языке бессмысленным.

Это сообщение отредактировал(а) Lukkoye - 13.11.2014, 22:27
PM MAIL   Вверх
Ihost
Дата 14.11.2014, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 14.9.2012

Репутация: нет
Всего: нет



Цитата(Lukkoye @  13.11.2014,  20:45 Найти цитируемый пост)
//(для компилятора gcc добиться такого поведения невозможно)
Эн нет- классическое свойства вида property работают только с элементами, передаваемыми по значению, и никаких ссылок и константных элементов они не подразумевают
В самом деле в том же C# вы можете передать и получить только значение!!! Да это может быть ссылочная переменная, указывающая на экземпляр класса или массива, но саму эту переменную получить по ссылке невозможно - для свойств не предусмотрен ref или out, так что непонятно о чем вообще речь
Можно сказать что в C++ property-свойства даже мощнее и функциональнее, так как можно реализовать их и с учетом ссылок, и константных объектов - шаблоны все это позволяют
Так что мой тезис в том, что свойства на C++ удобны, функциональны и удобны для применения, в то время как именованные функции GetX/SetX создают огромные неудобства и в клиентском, и библиотечном коде, и их использование при существовании нормальных свойств - бессмысленно

Цитата(xvr @  13.11.2014,  16:39 Найти цитируемый пост)
Ну например абсолютно С++ конструкция -
Да есть небольшие тонкости с дедукцией типов в шаблоне, но путем добавления еще одного аргумента можно получить, что нужно
Вообще язык шаблонов C++ является Тьюринг-полным, так что сделать в нем мануальную дедукцию типов и генерацию целевого шаблона не составит слишком большого труда
И напоследок пример, демонстрирующий неотличимое использование property-свойства для сложных подлежащих типов
Код

template <class T>
class Property : public T {  Property() { }
  operator T() const {
    return T::operator T();
  }
  T operator=(T const & value) {
    T::operator=(value);
    return value;
  }
};
template <class T> class Prop {  T data;
  Prop() : data() { }
  operator T() const {
    return data;
  }
  T operator=(T const & value) {
    data = value;
    return data;
  }
};
class myClass {public:
  Property<std::string> Name;
  Property<std::vector<std::string>> Ids;
Prop<int> Id;
  myClass() {
  }
};
template<class T1, class T2> bool MyFunc(T1 v1, T2 v2) {
    return (v1 < v2);
}
int main() {
    myClass thing;  thing.Name = "MySuperName";
    thing.Ids = {"1","2","3"};
   std::cout <<  thing.Name << std::endl;
   for(int i=0; i<thing.Ids.size(); i++) {
   std::cout << thing.Ids[i] << std::endl;
   }
   thing.Id = 100500;
   std::cout << thing.Id << std::endl;

   MyFunc(thing.Name, std::string("str"));

   MyFunc(thing.Id, 100);
}

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

**Единственная** сложность заключается только с функциями printf/scanf, или обобщенными вариадическими функциями в C-стиле, но если уж делать код в C-стиле, о каких подобных функциях можно вообще говорить - или делать нормальные вариадические шаблоны вокруг них, или ничего
Напоминаю что вариадические функции в C-стиле **воообще** ничего не знают о своих аргументах, и то что property не работают с ними автоматически, это проблемы не proprty, а отсутствия типизации в них


Обсуждение зашло довольно в сложную ситуацию, и причиной тому по всей видимости является разница в *логическом* и *техническом* понимании определенных элементов языка программирования
Допустим есть языки A и B, первый из которых поддерживает полноценное *синтаксическое* ООП с классами, наследованием и всеми необходимыми элементами, а второй - нет, но может вполне реализовать его с помощью синтаксического сахара
Есть программа на языке A, включающая один класс со статической функцией, и реализацию всей логики в ней; в программе на языке B с помощью синтаксического сахара определяюстся объекты и классы, есть четкая архитектура инкапсуляции и наследования
Какую из программ Вы считаете объектно-ориентированной? Мое мнение указывает, что только программа на языке B, поскольку в расчет берется не ситнактические, а архитектурные особенности! Ваше мнение видимо будет диаметрально противоположным, поэтому дальнейшая дискуссия бессмысленна


Это сообщение отредактировал(а) Ihost - 14.11.2014, 14:10
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0910 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.