Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 15:11
Оценка:
День добрый, есть задача перебить все WinAPI своими функциями. Вот кусок кода (маленький пример большой проблемы):


#include "windows.h"

#define CreateFile CreateFile_NWa // перебиваем имя функции своим

namespace NWa
{
  class CHandle;
  typedef CHandle * HANDLE; // определяем тип HANDLE
#define HANDLE NWa::HANDLE // перебиваем HANDLE своим типом
}

namespace NWa
{
  class CHandle // а вот и сам тип CHandle
  {
  public:
    HANDLE operator=(unsigned long*) { return NULL;}; // оператор присваивания
                                                      // из unsigned long* в HANDLE
};
}

HANDLE
CreateFile_NWa(
    LPCSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile
    );

unsigned long * Foo() // простая функция, возвращающая unsigned long *
{
    return NULL;
}

void main(void)
{
  HANDLE h = CreateFile("test.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

  HANDLE h2 = Foo(); // здесь компилятор выдает ошибку
                    // error C2440: 'initializing' : cannot convert from 'unsigned long *' to 'class NWa::CHandle *'
}



Почему?!
Re: Почему не срабатывает оператор присваивания
От: Bell Россия  
Дата: 27.08.07 15:17
Оценка:
Здравствуйте, slavo, Вы писали:

...
S>  HANDLE h2 = Foo(); // здесь компилятор выдает ошибку
S>                    // error C2440: 'initializing' : cannot convert from 'unsigned long *' to 'class NWa::CHandle *'


S>Почему?!


Потому что это есть так называемая инициализация копированием, и оператор присваивания здесь не используется. Для того, чтобы эта запись работала, необходим конструктор копирования и конструктор, принимающий в качестве параметра 'unsigned long *'.

Оператор присваивания будет работать при такой записи:
HANDLE h2;
h2 = Foo();
Любите книгу — источник знаний (с) М.Горький
Re: Почему не срабатывает оператор присваивания
От: Аноним  
Дата: 27.08.07 15:22
Оценка:
Здравствуйте, slavo, Вы писали:

S>День добрый, есть задача перебить все WinAPI своими функциями. Вот кусок кода (маленький пример большой проблемы):


А зачем? Сизифов труд однако.
Впрочем как знаете...

S>
S>  HANDLE h2 = Foo(); // здесь компилятор выдает ошибку
S>                    // error C2440: 'initializing' : cannot convert from 'unsigned long *' to 'class NWa::CHandle *'
S>


S>Почему?!


Ну а что ты ожидаешь?
Ты пытаешься сконвертировать указатель на unsigned long
в указатель на твой класс. Естественно что это невозможно.

А вообще, если таким вот стилем пытаетесь создать свою библиотеку классов,
для работы с виндой, то уже сразу можно предсказать провал.
Пользуйтесь лучше уже готовыми и проверенными библиотеками.
Re[2]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 15:23
Оценка:
Здравствуйте, Bell, Вы писали:


B>Оператор присваивания будет работать при такой записи:

B>
B>HANDLE h2;
B>h2 = Foo();
B>


Только что это проверил. Результат абсолютно такой же Т.е. не работает.
Re[2]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 15:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ты пытаешься сконвертировать указатель на unsigned long

А>в указатель на твой класс. Естественно что это невозможно.

Почему? Ведь этим и должен заниматься оператор присваивания. Разве нет?
Re[3]: Почему не срабатывает оператор присваивания
От: Bell Россия  
Дата: 27.08.07 15:29
Оценка: 4 (1)
Здравствуйте, slavo, Вы писали:

S>Здравствуйте, Bell, Вы писали:



B>>Оператор присваивания будет работать при такой записи:

B>>
B>>HANDLE h2;
B>>h2 = Foo();
B>>


S>Только что это проверил. Результат абсолютно такой же Т.е. не работает.


Я не правильно воспринял запись
HANDLE h2

я посчитал, что речь идет о
CHandle h2


В случае же с HANDLE все выглядит так:
CHandle* h2 = Foo();

Т.е. речь идет о присваивании указателей разных типов. Понятно, что это не будет компилиться, и CHandle::operator= не имеет никакого отношения к этой записи.
Любите книгу — источник знаний (с) М.Горький
Re[3]: Почему не срабатывает оператор присваивания
От: Аноним  
Дата: 27.08.07 15:33
Оценка: 4 (1)
Здравствуйте, slavo, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>Ты пытаешься сконвертировать указатель на unsigned long

А>>в указатель на твой класс. Естественно что это невозможно.

S>Почему? Ведь этим и должен заниматься оператор присваивания. Разве нет?


Твой оператор присваивания вообще никак не используется.

Кстати, читать такой код будет очень непросто,
учитывая, что HANDLE уже определен в глобальном namespace
Ты написал десяток строк, а уже фиг поймешь что к чему
Re[4]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 15:34
Оценка:
Здравствуйте, Bell, Вы писали:

B>Т.е. речь идет о присваивании указателей разных типов. Понятно, что это не будет компилиться, и CHandle::operator= не имеет никакого отношения к этой записи.


А можно ли как-нибудь подружить CHandle и HANDLE, чтобы оператор сравнения CHandle был действителен и для HANDLE?
Re[4]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 15:35
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>Кстати, читать такой код будет очень непросто,

А>учитывая, что HANDLE уже определен в глобальном namespace
А>Ты написал десяток строк, а уже фиг поймешь что к чему

Это лучшее решение одной огромной проблемы.
Re[4]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 15:38
Оценка:
Здравствуйте, Bell, Вы писали:

B>В случае же с HANDLE все выглядит так:

B>
B>CHandle* h2 = Foo();
B>

B>Т.е. речь идет о присваивании указателей разных типов. Понятно, что это не будет компилиться, и CHandle::operator= не имеет никакого отношения к этой записи.

Так тоже не работает. То же самое.
Re[5]: Почему не срабатывает оператор присваивания
От: Erop Россия  
Дата: 27.08.07 15:40
Оценка:
Здравствуйте, slavo, Вы писали:

А>>Ты написал десяток строк, а уже фиг поймешь что к чему

S>Это лучшее решение одной огромной проблемы.

А может лучше проблему опишешь?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Почему не срабатывает оператор присваивания
От: Bell Россия  
Дата: 27.08.07 15:41
Оценка:
Здравствуйте, slavo, Вы писали:

S>Здравствуйте, Bell, Вы писали:


B>>В случае же с HANDLE все выглядит так:

B>>
B>>CHandle* h2 = Foo();
B>>

B>>Т.е. речь идет о присваивании указателей разных типов. Понятно, что это не будет компилиться, и CHandle::operator= не имеет никакого отношения к этой записи.

S>Так тоже не работает. То же самое.

Я это и хотел сказать — это не может работать.

Может быть имеет смысл подробнее рассказать о своей "большой проблеме"? Глядишь, найдется адекватное решение...
Любите книгу — источник знаний (с) М.Горький
Re: Почему не срабатывает оператор присваивания
От: ncode  
Дата: 27.08.07 15:42
Оценка: 4 (1)
Здравствуйте, slavo, Вы писали:

S>День добрый, есть задача перебить все WinAPI своими функциями. Вот кусок кода (маленький пример большой проблемы):



S>
S>#include "windows.h"

S>#define CreateFile CreateFile_NWa // перебиваем имя функции своим

S>namespace NWa
S>{
S>  class CHandle;
S>  typedef CHandle * HANDLE; // определяем тип HANDLE
S>#define HANDLE NWa::HANDLE // перебиваем HANDLE своим типом
S>}
S>

Какой здесь смысл в неймспейсе если тут же дефайном открываем HANDLE в глобальной области и создаем себе кучу проблем?

S>
S>void main(void)
S>{

S>  HANDLE h2 = Foo(); // здесь компилятор выдает ошибку
S>                    // error C2440: 'initializing' : cannot convert from 'unsigned long *' to 'class NWa::CHandle *'
S>}
S>

S>Почему?!
Потому что здесь HANDLE — это указатель на CHandle, а реализованный оператор присваивания будет применятся к объекту CHandle.
Re[5]: Почему не срабатывает оператор присваивания
От: Аноним  
Дата: 27.08.07 15:43
Оценка:
Здравствуйте, slavo, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>Кстати, читать такой код будет очень непросто,

А>>учитывая, что HANDLE уже определен в глобальном namespace
А>>Ты написал десяток строк, а уже фиг поймешь что к чему

S>Это лучшее решение одной огромной проблемы.


Не верю. Это скорее похоже на порождение еще одной проблемы.
Re[6]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 15:45
Оценка:
Здравствуйте, Erop, Вы писали:

E>А может лучше проблему опишешь?


Проблема такая. Есть проект (около 400 Мб исходного кода). Его нужно портировать на Линукс. Соответсвенно от WinAPI нужно избавиться. Переписывать код нереально (чисто административно). Остается только перебить существующий.
Re[2]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 15:49
Оценка:
Здравствуйте, ncode, Вы писали:

N>Какой здесь смысл в неймспейсе если тут же дефайном открываем HANDLE в глобальной области и создаем себе кучу проблем?


Смысл — определить свой тип HANDLE. Не вызывая ошибку переопределения, которое уже сделано в windows.h.

N>Потому что здесь HANDLE — это указатель на CHandle, а реализованный оператор присваивания будет применятся к объекту CHandle.


Угу, это я понял. А как их подружить?
Re[3]: Почему не срабатывает оператор присваивания
От: ncode  
Дата: 27.08.07 16:08
Оценка: 6 (1)
Здравствуйте, slavo, Вы писали:

S>Здравствуйте, ncode, Вы писали:


N>>Какой здесь смысл в неймспейсе если тут же дефайном открываем HANDLE в глобальной области и создаем себе кучу проблем?


S>Смысл — определить свой тип HANDLE. Не вызывая ошибку переопределения, которое уже сделано в windows.h.


Не стоит использовать для своих типов имена типа HANDLE — это приведет к полному хаосу в коде. В данном случае делают обертки над существующими типами. Вот хороший пример обертки для HANDLE:
//взято из atlbase.h
class CHandle
{
public:
    CHandle() throw();
    CHandle( CHandle& h ) throw();
    explicit CHandle( HANDLE h ) throw();
    ~CHandle() throw();

    CHandle& operator=( CHandle& h ) throw();

    operator HANDLE() const throw();

    // Attach to an existing handle (takes ownership).
    void Attach( HANDLE h ) throw();
    // Detach the handle from the object (releases ownership).
    HANDLE Detach() throw();

    // Close the handle.
    void Close() throw();

public:
    HANDLE m_h;
};


Тогда твой код будет выглядет примерно так:
void main(void)
{
  CHandle h = CreateFile("test.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  CHandle h2 = Foo();
}
Re[4]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 16:17
Оценка:
Здравствуйте, ncode, Вы писали:

N>Тогда твой код будет выглядет примерно так:

N>
N>void main(void)
N>{
N>  CHandle h = CreateFile("test.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
N>  CHandle h2 = Foo();
N>}
N>


Именно так оно и будет. Только в существующем коде ничего нельзя менять. В коде должен быть везде HANDLE.
Re[7]: Почему не срабатывает оператор присваивания
От: Кодт Россия  
Дата: 27.08.07 16:37
Оценка:
Здравствуйте, slavo, Вы писали:

S>Проблема такая. Есть проект (около 400 Мб исходного кода). Его нужно портировать на Линукс. Соответсвенно от WinAPI нужно избавиться. Переписывать код нереально (чисто административно). Остается только перебить существующий.


Или прикрутить Wine.
К переизобретению которого, похоже, всё и приведёт...
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[8]: Почему не срабатывает оператор присваивания
От: slavo  
Дата: 27.08.07 16:49
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Или прикрутить Wine.

К>К переизобретению которого, похоже, всё и приведёт...

Wine не подходит.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.