none
Перегрузка операторов RRS feed

  • Вопрос

  • У меня примерно такая ситуация:

    Есть класс Strings для хранения и обработки строки в двух вариантах - String ^ и char * (что бы не было лишних вопросов по названию класса - прошу обратить внимание на последнюю букву в имени класса).

    Главное поле этого класса  - String ^str;

    Вопрос: как для главного поля класса реализовать перегрузку оператора ? Любого, но пока планируется =, +=, ==, !=, [].

    Забыл: предпочитаемый язык - C++, версия студии - 2013, платформа .NET 4.5.
    17 марта 2014 г. 15:31

Ответы

  • Также, как и в native С++. Вот пара примеров:

    Strings ^ operator = (Strings ^right) { str = right->str; return this; } Strings ^ operator + (Strings ^right) {

    // предполагается, что есть такой конструктор return gcnew Strings(str + right->str); }


    Далее по этой схеме :)


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


    • Изменено kosuke904 17 марта 2014 г. 21:20
    • Помечено в качестве ответа programmist_0 21 марта 2014 г. 13:41
    17 марта 2014 г. 21:18
  • Для того, чтобы можно было преобразовать нечто в объект Вашего класса, нужен соответствующий конструктор:

    // конструктор из String
    Strings(String ^s)
    {
    	str = s;
    }
    
    // конструктор из массива символов
    Strings(char *s)
    {
    	str = gcnew String(s);
    }
    
    // и т.д.
    

    У меня слово operator тоже не подсвечивается, но все работает :)


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа programmist_0 21 марта 2014 г. 13:41
    18 марта 2014 г. 6:07
  • А объекты создаем так:

    Strings ^s1 = gcnew Strings("qwerty");


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа programmist_0 21 марта 2014 г. 13:41
    18 марта 2014 г. 6:10
  • Чувствую, Вы не совсем понимаете синтаксис C++/CLI. Вот тут информация об этом (и о дескрипторах и о ссылках).

    Привожу новый вариант класса. Обратите внимание на альтернативный синтаксис создания объектов (видимо, Вы этого хотели)

    ref class Strings
    {
    	// внутреннее хранилище символов
    	// поле типа char * объявлять нет смысла,
    	// т.к. можно обойтись одним
    	String ^str;
    
    public:
    
    	// конструктор по умолчанию
    	Strings()
    	{
    		str = String::Empty;
    	}
    
    	// конструктор из String
    	Strings(String ^s)
    	{
    		str = s;
    	}
    
    	// конструктор из массива символов
    	Strings(const char *s)
    	{
    		str = gcnew String(s);
    	}
    
    	// присваивание дескриптора
    	Strings ^operator = (Strings ^right)
    	{
    		str = right->str;
    		return this;
    	}
    
    	// присваивание ссылки
    	Strings% operator = (Strings %right)
    	{
    		str = right.str;
    		return *this;
    	}
    
    	// присваивание указателя на массив символов
    	Strings% operator = (const char *right)
    	{
    		str = gcnew String(right);
    		return *this;
    	}
    };
    
    void main()
    {
    	// дескрипторы
    	Strings ^h1, ^h2;
    	
    	// создание объекта из String
    	// компилятор сам создает объект String
    	// из константной строки
    	h1 = gcnew Strings("aaa");
    
    	// это не присваивание, а создание
    	// новой ссылки на тот же объект
    	h2 = h1;
    	
    	/*
    		альтернативный синтаксис создания объекта
    	*/
    
    	// конструктор из String
    	Strings s1("bbb");
    
    	// конструктор из массива символов
    	char s[] = "qwerty";
    	Strings s2(s);
    
    	// конструктор по умолчанию
    	Strings s3;
    
    	// присваивание дескриптора
    	s3 = h1;
    
    	// присваивание ссылки
    	s3 = s1;
    
    	// присваивание массива
    	s3 = "ccc";
    }
    


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа programmist_0 21 марта 2014 г. 13:40
    19 марта 2014 г. 10:56

Все ответы

  • Также, как и в native С++. Вот пара примеров:

    Strings ^ operator = (Strings ^right) { str = right->str; return this; } Strings ^ operator + (Strings ^right) {

    // предполагается, что есть такой конструктор return gcnew Strings(str + right->str); }


    Далее по этой схеме :)


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


    • Изменено kosuke904 17 марта 2014 г. 21:20
    • Помечено в качестве ответа programmist_0 21 марта 2014 г. 13:41
    17 марта 2014 г. 21:18
  • Также, как и в native С++. Вот пара примеров:

    Strings ^ operator = (Strings ^right) { str = right->str; return this; } Strings ^ operator + (Strings ^right) {

    // предполагается, что есть такой конструктор return gcnew Strings(str + right->str); }


    Далее по этой схеме :)


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


    Собственно, пишу:

    Strings ^ operator = (Strings ^equalreload) // слово "operator" никак не выделяется
    {
    	str=equalreload->str;
    	return this;
    }

    Тут ошибок нет. Но дальше:

    Strings ^mystr; // экземпляр моего класса, без ошибок объявляется только дескриптором
    String ^default; // банальнейшая строка класса System::String
    
    mystr="чё нибудь"; // ошибка: невозможно преобразовать "const char [10]" в "Strings ^"
    mystr=default; // ошибка: невозможно преобразовать "System::String ^" в "Strings ^"

    Надеюсь на помощь ...

    Но скорее всего  просто чего то неправильно понял ... Опять же, надеюсь, что поможете разобраться ...

    18 марта 2014 г. 0:35
  • Для того, чтобы можно было преобразовать нечто в объект Вашего класса, нужен соответствующий конструктор:

    // конструктор из String
    Strings(String ^s)
    {
    	str = s;
    }
    
    // конструктор из массива символов
    Strings(char *s)
    {
    	str = gcnew String(s);
    }
    
    // и т.д.
    

    У меня слово operator тоже не подсвечивается, но все работает :)


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа programmist_0 21 марта 2014 г. 13:41
    18 марта 2014 г. 6:07
  • А объекты создаем так:

    Strings ^s1 = gcnew Strings("qwerty");


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа programmist_0 21 марта 2014 г. 13:41
    18 марта 2014 г. 6:10
  • А объекты создаем так:

    Strings ^s1 = gcnew Strings("qwerty");


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    Я конечно извиняюсь, но я всё же не понял ... Конструктор у моего класса есть, а как использовать много конструкторов - я не понимаю.

    Я выложил код класса сюда - http://pastebin.com/RGsNmJFE 

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

    На данном примере я уже буду пытаться реализовать перегрузку других операторов.

    В конце концов экземпляр класса System::String ^ для первоначального создания объекта не требует оператора gcnew (ну или я не понял, куда этот gcnew пихать ... ).

    И да - извиняюсь за такой уровень наглости.

    18 марта 2014 г. 15:35
  • Вот как-то так я это себе представляю:

    ref class Strings
    {
    	String ^str;
    
    public:
    
    	// конструктор из String
    	Strings(String ^s)
    	{
    		str = s;
    	}
    
    	// конструктор из массива символов
    	Strings(const char *s)
    	{
    		str = gcnew String(s);
    	}
    
    	Strings ^ operator = (Strings ^right)
    	{
    		str = right->str;
    		return this;
    	}
    };
    
    int main()
    {
    	Strings ^s1 = gcnew Strings("qq");
    	Strings ^s2 = gcnew Strings("ww");
    
    	s1 = s2;
    	s1 = gcnew Strings("qwerty");
    
    	return 0;
    }
    

    Операцию присваивания char * компилятор принимает, но код в main типа

    s1 = "qwerty";

    принимать не хочет, пока не могу понять, почему. Альтернативный вариант предложен в main.

    По поводу количества конструкторов: делайте столько, сколько нужно для разнообразного создания объектов класса. Они должны отличаться типами или количеством параметров.

    И еще. В конце концов экземпляр класса System::String ^ для первоначального создания объекта не требует оператора gcnew - объявление переменной типа Strings ^ - это не объект, это дескриптор объекта. Реальный объект создает исключительно gcnew.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    18 марта 2014 г. 21:09
  • Вот как-то так я это себе представляю:

    ref class Strings
    {
    	String ^str;
    
    public:
    
    	// конструктор из String
    	Strings(String ^s)
    	{
    		str = s;
    	}
    
    	// конструктор из массива символов
    	Strings(const char *s)
    	{
    		str = gcnew String(s);
    	}
    
    	Strings ^ operator = (Strings ^right)
    	{
    		str = right->str;
    		return this;
    	}
    };
    
    int main()
    {
    	Strings ^s1 = gcnew Strings("qq");
    	Strings ^s2 = gcnew Strings("ww");
    
    	s1 = s2;
    	s1 = gcnew Strings("qwerty");
    
    	return 0;
    }

    Операцию присваивания char * компилятор принимает, но код в main типа

    s1 = "qwerty";

    принимать не хочет, пока не могу понять, почему. Альтернативный вариант предложен в main.

    По поводу количества конструкторов: делайте столько, сколько нужно для разнообразного создания объектов класса. Они должны отличаться типами или количеством параметров.

    И еще. В конце концов экземпляр класса System::String ^ для первоначального создания объекта не требует оператора gcnew - объявление переменной типа Strings ^ - это не объект, это дескриптор объекта. Реальный объект создает исключительно gcnew.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    Это конечно круто, но использование gcnew не упрощает использование объектов моего класса, всего лишь только добавит возможность синхронизации значений (при изменении str изменить char * и наоборот).

    В этом случае легче реализовать приоритет изменения (синхронизация при изменении какого то одного поля), чем описывать кучу конструкторов, а в результате получить gcnew.

    Ну, в принципе, вполне логичный вопрос: как создать дескриптор и связать его с объектом класса ? Как я понял - дескриптор является некой прослойкой между интерфейсом доступа и объектом класса.


    18 марта 2014 г. 22:55
  • Чувствую, Вы не совсем понимаете синтаксис C++/CLI. Вот тут информация об этом (и о дескрипторах и о ссылках).

    Привожу новый вариант класса. Обратите внимание на альтернативный синтаксис создания объектов (видимо, Вы этого хотели)

    ref class Strings
    {
    	// внутреннее хранилище символов
    	// поле типа char * объявлять нет смысла,
    	// т.к. можно обойтись одним
    	String ^str;
    
    public:
    
    	// конструктор по умолчанию
    	Strings()
    	{
    		str = String::Empty;
    	}
    
    	// конструктор из String
    	Strings(String ^s)
    	{
    		str = s;
    	}
    
    	// конструктор из массива символов
    	Strings(const char *s)
    	{
    		str = gcnew String(s);
    	}
    
    	// присваивание дескриптора
    	Strings ^operator = (Strings ^right)
    	{
    		str = right->str;
    		return this;
    	}
    
    	// присваивание ссылки
    	Strings% operator = (Strings %right)
    	{
    		str = right.str;
    		return *this;
    	}
    
    	// присваивание указателя на массив символов
    	Strings% operator = (const char *right)
    	{
    		str = gcnew String(right);
    		return *this;
    	}
    };
    
    void main()
    {
    	// дескрипторы
    	Strings ^h1, ^h2;
    	
    	// создание объекта из String
    	// компилятор сам создает объект String
    	// из константной строки
    	h1 = gcnew Strings("aaa");
    
    	// это не присваивание, а создание
    	// новой ссылки на тот же объект
    	h2 = h1;
    	
    	/*
    		альтернативный синтаксис создания объекта
    	*/
    
    	// конструктор из String
    	Strings s1("bbb");
    
    	// конструктор из массива символов
    	char s[] = "qwerty";
    	Strings s2(s);
    
    	// конструктор по умолчанию
    	Strings s3;
    
    	// присваивание дескриптора
    	s3 = h1;
    
    	// присваивание ссылки
    	s3 = s1;
    
    	// присваивание массива
    	s3 = "ccc";
    }
    


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа programmist_0 21 марта 2014 г. 13:40
    19 марта 2014 г. 10:56
  • Чувствую, Вы не совсем понимаете синтаксис C++/CLI. Вот тут информация об этом (и о дескрипторах и о ссылках).

    Привожу новый вариант класса. Обратите внимание на альтернативный синтаксис создания объектов (видимо, Вы этого хотели)

    ref class Strings
    {
    	// внутреннее хранилище символов
    	// поле типа char * объявлять нет смысла,
    	// т.к. можно обойтись одним
    	String ^str;
    
    public:
    
    	// конструктор по умолчанию
    	Strings()
    	{
    		str = String::Empty;
    	}
    
    	// конструктор из String
    	Strings(String ^s)
    	{
    		str = s;
    	}
    
    	// конструктор из массива символов
    	Strings(const char *s)
    	{
    		str = gcnew String(s);
    	}
    
    	// присваивание дескриптора
    	Strings ^operator = (Strings ^right)
    	{
    		str = right->str;
    		return this;
    	}
    
    	// присваивание ссылки
    	Strings% operator = (Strings %right)
    	{
    		str = right.str;
    		return *this;
    	}
    
    	// присваивание указателя на массив символов
    	Strings% operator = (const char *right)
    	{
    		str = gcnew String(right);
    		return *this;
    	}
    };
    
    void main()
    {
    	// дескрипторы
    	Strings ^h1, ^h2;
    	
    	// создание объекта из String
    	// компилятор сам создает объект String
    	// из константной строки
    	h1 = gcnew Strings("aaa");
    
    	// это не присваивание, а создание
    	// новой ссылки на тот же объект
    	h2 = h1;
    	
    	/*
    		альтернативный синтаксис создания объекта
    	*/
    
    	// конструктор из String
    	Strings s1("bbb");
    
    	// конструктор из массива символов
    	char s[] = "qwerty";
    	Strings s2(s);
    
    	// конструктор по умолчанию
    	Strings s3;
    
    	// присваивание дескриптора
    	s3 = h1;
    
    	// присваивание ссылки
    	s3 = s1;
    
    	// присваивание массива
    	s3 = "ccc";
    }


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    Я не могу понять, почему у меня компилятор не принимает "альтернативный синтаксис":

    	// конструктор из String
    	Strings s1("bbb");

    Тут ошибка

    " значение типа "const char *" нельзя использовать для инициализации сущности типа "Strings ^ ".

    Может я какой то "не нужный мне" конструктор не добавил ?

    	// присваивание указателя на массив символов
    	Strings% operator = (const char *right)
    	{
    		str = gcnew String(right);
    		return *this;
    	}
    	// присваивание массива
    	s3 = "ccc";
    Тут тоже компилятор ругается.
    20 марта 2014 г. 16:13
  • Совсем не обязательно включать в цитату весь ответ. Откровенно говоря, мне уже скучно :) Я Вам еще в предыдущем Вашем посте пытался донести мысль о том, что научиться писать программы исключительно чужими советами нельзя. У Вас существенные пробелы в знании языка программирования. Учитесь, читайте литературу. Данный форум не имеет цели научить. Его назначение, как я понимаю, посоветовать наиболее правильное решение конкретной проблемы. Всего наилучшего.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    20 марта 2014 г. 19:27
  • Совсем не обязательно включать в цитату весь ответ. Откровенно говоря, мне уже скучно :) Я Вам еще в предыдущем Вашем посте пытался донести мысль о том, что научиться писать программы исключительно чужими советами нельзя. У Вас существенные пробелы в знании языка программирования. Учитесь, читайте литературу. Данный форум не имеет цели научить. Его назначение, как я понимаю, посоветовать наиболее правильное решение конкретной проблемы. Всего наилучшего.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    Плохого вы обо мне мнения, если думаете, что я пользуюсь только вашими советами ... Да и вообще, советами, как таковыми. Часто читаю справки (которые часто неполные), иду скажем так на ощупь: получиться - и хорошо, не получиться - далее щупаю.
    21 марта 2014 г. 13:39
  • компилятор ругается.

    Всё не читал, лишь бегло просмотрел. Отмечу, что в .NET строки являются юникодными. Следовательно, тип System::Char занимает два байта (суррогатные пары - больше).

    В нативном C++ есть однобайтовый тип char и многобайтовый тип wchar. Литералы последнего типа записываются с префиксом L, то есть вот так: L"abc".

    Возможно, проблемы из-за неправильного употребления символов/строк разных кодировок?

    21 марта 2014 г. 14:34