Тема: Погано розумію перевантаження операторів та таке всяке.

Доброї ночі!

Ось такий вираз
stri += (MSTR)strj;
Я ледь башню собі не зламав думаючи що це. Чи то помилка, описка, чи то що це було задумано або що могло тут бути.
Що могло б підрозуміватіся?

MSTR- це клас!   strj це масив, stri  об'єкт класу MSTR. Мені це взагалі не зрозуміло! Як слона схрестили з бегемотом, вони ж зовсім ризні!
Я щось не розумію зовсим , ниякого сенсу.

Тобто я бачу звичайно що

Ничого я не бачу! Розтулмачте мені будь ласка!

Ось цей конкретний файл

// FILE dlgs.cpp
//
// use: libcmt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib 
// shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib
//
// ignore: libc.lib

#ifndef _MT
#define _MT
#endif

#include <windows.h>

#include <winbase.h>
#include <process.h>
#include <commctrl.h>

#include <string.h>
#include <stdio.h>

#include "ModalD.h"
#include "mstr.h"

#include "dlgs.rou"
#include "dlgs.var"

int WINAPI WinMain (HINSTANCE hThisInst,HINSTANCE hPrevInst,LPSTR lpszArgs,int nWinMode)
{
    ::SetUnhandledExceptionFilter (UEFilter);
    ::InitCommonControls();
    pmodalDialog = new ModalD(hThisInst,NULL);
                             if (pmodalDialog == NULL) ApplicationTerminate (0x666);

    return pmodalDialog->ShowModalDialog ("MYDG");
}
// *** Subroutines ***
LONG WINAPI UEFilter (PEXCEPTION_POINTERS pExceptionInfo)
{ 
 DecodeError ("Application Threads Exception", pExceptionInfo->ExceptionRecord->ExceptionCode);
 return EXCEPTION_EXECUTE_HANDLER ;
}
void WINAPI DecodeError (char *pCaption, DWORD errcode)
{
char strj [80];
MSTR stri;

  switch (errcode)
  {
   case EXCEPTION_ACCESS_VIOLATION:         stri = "EXCEPTION_ACCESS_VIOLATION";         break;
   case EXCEPTION_BREAKPOINT:               stri = "EXCEPTION_BREAKPOINT";               break;
   case EXCEPTION_DATATYPE_MISALIGNMENT:    stri = "EXCEPTION_DATATYPE_MISALIGNMENT";    break;
   case EXCEPTION_SINGLE_STEP:              stri = "EXCEPTION_SINGLE_STEP";              break;
   case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:    stri = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";    break;
   case EXCEPTION_FLT_DENORMAL_OPERAND:     stri = "EXCEPTION_FLT_DENORMAL_OPERAND";     break;
   case EXCEPTION_FLT_DIVIDE_BY_ZERO:       stri = "EXCEPTION_FLT_DIVIDE_BY_ZERO";       break;
   case EXCEPTION_FLT_INEXACT_RESULT:       stri = "EXCEPTION_FLT_INEXACT_RESULT";       break;
   case EXCEPTION_FLT_INVALID_OPERATION:    stri = "EXCEPTION_FLT_INVALID_OPERATION";    break;
   case EXCEPTION_FLT_OVERFLOW:             stri = "EXCEPTION_FLT_OVERFLOW";             break;
   case EXCEPTION_FLT_STACK_CHECK:          stri = "EXCEPTION_FLT_STACK_CHECK";          break;
   case EXCEPTION_FLT_UNDERFLOW:            stri = "EXCEPTION_FLT_UNDERFLOW";            break;
   case EXCEPTION_INT_DIVIDE_BY_ZERO:       stri = "EXCEPTION_INT_DIVIDE_BY_ZERO";       break;
   case EXCEPTION_INT_OVERFLOW:             stri = "EXCEPTION_INT_OVERFLOW";             break;
   case EXCEPTION_PRIV_INSTRUCTION:         stri = "EXCEPTION_PRIV_INSTRUCTION";         break;
   case EXCEPTION_NONCONTINUABLE_EXCEPTION: stri = "EXCEPTION_NONCONTINUABLE_EXCEPTION"; break;

   default: 
           errcode &= 0xFFFF;
           if (errcode == 0) return ;
           else stri = "SOFT RISED EXCEPTION"; 
   break;
  }
  sprintf (strj,"  Exception code=0x%0x", errcode);

  stri += (MSTR)strj;
  type_message (stri, pCaption, 0); 
}
void WINAPI type_message (LPCTSTR lpText, LPCTSTR lpCaption, UINT info)
{
UINT style;

  style = MB_OK;
  switch (info)
  {
   case 0: style |= MB_ICONERROR;       break;
   case 1: style |= MB_ICONEXCLAMATION; break;
  }
  ::MessageBox (NULL,lpText,lpCaption,style);
}
void WINAPI ApplicationTerminate (int code)
{
 ::RaiseException
 (
  (EXCEPTION_ACCESS_VIOLATION & 0xFFFF0000) | (code & 0xFFFF),   //EXCEPTION_ACCESS_VIOLATION - спроба читання або запису за адресою віртуальної пам'яті, до якої процес не має доступу.
  EXCEPTION_NONCONTINUABLE,
  0,
  NULL
 );
}

91 17 C:\Bloc\D6\dls.cpp [Error] no match for 'operator+=' in 'stri += MSTR(((char*)(& strj)))'

Подякували: 0xDADA11C71

2 Востаннє редагувалося koala (23.12.2015 00:08:14)

Re: Погано розумію перевантаження операторів та таке всяке.

В C++ є кілька різних способів конвертувати типи.

A a;
B b;
//Неявний:
a=b; //b буде перетворено в A, якщо є якийсь спосіб для цього - наприклад, конструктор A(B) чи A::operator=(B)
//Стиль C:
a=(A)b; //ваш випадок
//C++ конструктор:
a=A(b);
//C++ cast:
a=якийсь_там_cast<A>(b);

cast-ів існує 4, але будь-який з них (добре, крім const_cast) буде, знову ж таки, шукати конструктор чи оператор =. Але саме cast-и вважаються коректним способом - щоб нагадати, що перетворення типів слід уникати, і треба робити щось інше, а не писати cast-и.
Щоб ще щось сказати, треба бачити код mstr.h.
І 90% коду, що ви навели, не стосується питання, могли б і почистити.

Подякували: Дмитро-Чебурашка1

3

Re: Погано розумію перевантаження операторів та таке всяке.

А до чого тут "перевантаження" ?

4

Re: Погано розумію перевантаження операторів та таке всяке.

cheappi386 написав:

А до чого тут "перевантаження" ?

Ні до чого. Це ти сам же зв'язав перевантаження та кастування.
Ніякого перевантаження тут немає.

5

Re: Погано розумію перевантаження операторів та таке всяке.

cheappi386 написав:

А до чого тут "перевантаження" ?

Бо operator += треба перевантажити.

6

Re: Погано розумію перевантаження операторів та таке всяке.

koala написав:

Бо operator += треба перевантажити.

Тут згоден. Операцію таку доведеться описати перевантаженням.

7 Востаннє редагувалося Дмитро-Чебурашка (25.12.2015 02:23:37)

Re: Погано розумію перевантаження операторів та таке всяке.

Дякую всім!

Мене цікавить не готовий результат, а пояснення.

Я викладу все разом, ви вже вибачте мене. Там коду не багато але і не замало. Якщо ви відкриєте проэкт в середовищі  то відразу ж швидко все знайдете.
Я дійсно думаю, що так буде краще. Не дивитьс будь ласка в коді мої коментарі, бо я лише заплутаю і вас та себе.

Розяснення, посилання на інформацію, пояснення рядків трьох - п'ять - десять, який самє потрібен оператор або конструктор!
http://сайт-злодій/file/3170073

P.s/ Краще усе одразу!

Код таки

class MSTR 
{
 private:

  int WINAPI get_size_str (char *sp); // Отримати номер рядка
 void WINAPI pdata_free (void);       // звільнити зайняті ресурси під дані
  int WINAPI Compare_Strings (char *p1, char *p2);
  int WINAPI Compare_Strings (char *p1, char *p2, int size)  ;

 char err_data;                       // dummy byte
 char *pdata;                         // Покажчік на рядок даних

 BOOL status;                         // TRUE - все OK
 int size_;                           // размір рядка включаючі 0x00

 public:
          WINAPI  MSTR ();
         WINAPI  MSTR (char *pstr);
         WINAPI  MSTR (MSTR&);                        // конструктор копий
 virtual WINAPI ~MSTR ();

  BOOL WINAPI GetStatusOK (void);     // получить статус. TRUE - OK
 
 MSTR& WINAPI operator=(char *sou);   // Операція привласненняя
 MSTR& WINAPI operator=(MSTR& sou);   // Операція привласнення
 MSTR  WINAPI operator+(MSTR& sou);   // скласти рядки
 MSTR& WINAPI operator+=(MSTR& sou);  // збільшити рядок
 BOOL  WINAPI operator==(MSTR& sou);  // порівняти рядки
 BOOL  WINAPI operator!=(MSTR& sou);  // порівняти рядки
 BOOL  WINAPI operator==(char *sou);  // порівняти рядки
 BOOL  WINAPI operator!=(char *sou);  // порівняти рядки

 BOOL  WINAPI write_byte (char b, int offset); // змінити байт n рядка почінаючі з 0
 BOOL  WINAPI read_byte  (char *pb, int offset);
 BOOL  WINAPI SetSize (int size);     // змінити розмір

// операція перетворення типу 
 operator char * ();   
 operator unsigned char * ();  
 operator int ()          {return (size_-1);}
 operator unsigned int () {return (unsigned int)(size_-1);}
};
//---------------------------------------------------------------------------
#endif

Re: Погано розумію перевантаження операторів та таке всяке.

Я заплутавсь. Нехай я тупий, але розпішить докладніше, який такий мій випадок і що в моєму коді потрібно. А то мені ніби цікаво, я майже що то зрозумів, а код собі виправити не можу!

9 Востаннє редагувалося koala (28.12.2015 22:02:18)

Re: Погано розумію перевантаження операторів та таке всяке.

На щось менш вірусне викласти можете?
Вангую, до речі, що нема визначення оператора += в .cpp-файлі.

10

Re: Погано розумію перевантаження операторів та таке всяке.

Не розумієте елементарного, а на обробку винятків око поклали. Так жить нізя!

11

Re: Погано розумію перевантаження операторів та таке всяке.

Гм... який компілятор і яке перше повідомлення про помилку при компіляції MSTR.cpp у вас?

12

Re: Погано розумію перевантаження операторів та таке всяке.

koala написав:

який компілятор

тільки DOS компілятор буде кидати код на депозіт )))

Подякували: koala1

13 Востаннє редагувалося Дмитро-Чебурашка (29.12.2015 22:11:53)

Re: Погано розумію перевантаження операторів та таке всяке.

Компілятор Dev-C++ 5.4.0,  перше повідомлення про помилку це саме,
91 17 C:\Bloc\D6\dls.cpp [Error] no match for 'operator+=' in 'stri += MSTR(((char*)(& strj)))'

14

Re: Погано розумію перевантаження операторів та таке всяке.

Dev-C++ - не компілятор, а IDE, компілятор в 5.4.0 - gcc 4.7.2. Але ок.
Кілька наступних рядків в повідомленні компілятора ви не дивилися? Там написано, що компілятор не може знайти перетворення, найближчий кандидат -

MSTR& MSTR::operator+=(MSTR&)

Чому ж цей оператор не приймає такі параметри? Бо ви хочете, щоб він приймав посилання на MSTR. Але жодного реального MSTR ви йому не даєте, а даєте проміжний результат операції (MSTR)strj. Проміжні результати "живуть" недовго, тому така дія є небезпечною. Як вийти з ситуації? Змінити визначення оператора. Або передавайте йому об'єкт MSTR (так, це буде коштувати вам цілу операцію копіювання, що не дуже ефективно), або передавайте константе посилання:

const MSTR& MSTR::operator+=(const MSTR&)

Тепер компілятор знатиме, що в operator+= можуть передати якусь гидоту, в яку писати не варто, і дозволить це. Зверніть увагу, що я змінив також тип результату на константний - щоб уникнути ризику несподіваної поведінки чогось подібного до

(a+=b).change();//змінює об'єкт a, а не тимчасовий результат

А в цілому - жах, а не код. Будь ласка, увімкніть всі попередження компілятора і щось зробіть, щоб їх не було. Бо на вас чекає ще стільки проблем...