Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > при создание класса иногда должно возвращатся NULL


Автор: Incinerated 18.2.2009, 15:48
Поискав на форуме нашел некоторые вещи, но что то не получается. Вот хеадер класса:
Код

class TWorkWithServer{
private:
  SOCKET sServer;
  SOCKADDR_IN InetAddr;
  WSADATA wsaData;

  TWorkWithServer();
public:
  static TWorkWithServer* Create(char* ip,DWORD port);
  ~TWorkWithServer();
};

а вот cpp:
Код

TWorkWithServer* TWorkWithServer::Create(char* ip,DWORD port){
  if(!WSAStartup(0x0202,&wsaData))
  {
    if((sServer = socket(AF_INET,SOCK_STREAM,0)) != INVALID_SOCKET)
    {
      InetAddr.sin_family      = AF_INET;
      InetAddr.sin_addr.s_addr = inet_addr(ip);
      InetAddr.sin_port        = htons(port);
      if(!connect(sServer,(struct sockaddr *)&InetAddr,sizeof(InetAddr)) != SOCKET_ERROR)
      {
        return NULL;
      }
      else
        return new TWorkWithServer;
    }
    else
      return NULL;
  }
  else
    return NULL;
}

TWorkWithServer::TWorkWithServer(){
}

TWorkWithServer::~TWorkWithServer()
{
}

В cpp-файл не компилится. :( Пишется ошибка [C++ Error] TWorkWithServer.cpp(24): E2034 Cannot convert 'WSAData TWorkWithServer::*' to 'WSAData *'. Я так понимаю нельзя работать с объектами... а что можно сделать?
создаю так:
Код

TWorkWithServer *WorkServer(TWorkWithServer::Create("127.0.0.1",3333));

т.е. смысл такой, если к серверу по заданному ай-пи и порту нельзя подключится, то нужно вернуть NULL при создании экземпляра данного класса. 

Автор: Dem_max 18.2.2009, 16:20
Вот для примера
Код

#include <winsock2.h>
#include <tchar.h>
#include "LIRCserver.h"


//---------------------------------------------------------------------------
bool TWinLIRCServer::Init(void)
{
   WSAData  wsa_data;
   flWSAStartUp = false;
   if(WSAStartup(MAKEWORD(2, 0), &wsa_data)) //  можно вынести в конструктор
   {
      TCHAR Msg[100];
      wsprintf(Msg, _T("An error occurred while loading the network library. Error: %d "), WSAGetLastError());
      MessageBox(0, Msg, _T("Error !!!"), MB_ICONERROR | MB_OK);
      return TRUE;
   }
   return FALSE;
}
//---------------------------------------------------------------------------

int TWinLIRCServer::StartServer(char* IP_Adress, unsigned int Port)
{
   DWORD IP;
   if(!flWSAStartUp) return OTHER_ERROR;

}
//---------------------------------------------------------------------------
void TWinLIRCServer::StopServer(void)
{

}        


TWinLIRCServer::TWinLIRCServer()
{

}

TWinLIRCServer::~TWinLIRCServer()
{

    WSACleanup();
}



Код

#ifndef WINLIRC_SERVER_H
#define WINLIRC_SERVER_H

class TWinLIRCServer
{
   public:
      bool Init(void);
      void UnInit(void);
       int StartServer(char* IP_Adress, unsigned int Port);

   private:
       SOCKET ServerSocket;
       SOCKET ClientSocket;
      SOCKADDR_IN SocketAddress;
      HANDLE hEventServer;
      HANDLE hEventClient;
      HANDLE hThreadServer;
      bool flServerStarted;
      bool flWSAStartUp;
};

#endif


Автор: Lazin 18.2.2009, 16:22
на какую строчку ругается?

Автор: Incinerated 18.2.2009, 16:27
Цитата(Lazin @ 18.2.2009,  16:22)
на какую строчку ругается?

первую в функции
Код

if(!WSAStartup(0x0202,&wsaData))


to DemMax это я и сам знаю что так можно сделать... а мне нужно чтобы, например, я делаю TWorkWithBase *temp = new TWorkWithBase("127.0.0.1",3333); если не подключилось, вернулось в переменную temp NULL. В некоторых закрытых классах это реализовано, мне нужно знать как...

Автор: Dem_max 18.2.2009, 16:33
Incinerated, 
Ты лучше бы показал текст ошибки, а то сидий гадай на что ругается.

Автор: Incinerated 18.2.2009, 16:58
Цитата(Dem_max @ 18.2.2009,  16:33)
Incinerated, 
Ты лучше бы показал текст ошибки, а то сидий гадай на что ругается.

Я писал...в первом посте....
Цитата

Пишется ошибка [C++ Error] TWorkWithServer.cpp(24): E2034 Cannot convert 'WSAData TWorkWithServer::*' to 'WSAData *'

Автор: Lazin 18.2.2009, 19:38
у gcc какие-то загадочные сообщения об ошибках smile 
Create - статический метод класса, а ты пытаешься получить из него доступ к нестатическим членам класса

Автор: Dem_max 19.2.2009, 09:36
кстати незаметил, а зачем ты Create(char* ip,DWORD port); делаешь статическим ?

Автор: mes 19.2.2009, 10:05
Цитата(Dem_max @  19.2.2009,  08:36 Найти цитируемый пост)
кстати незаметил, а зачем ты Create(char* ip,DWORD port); делаешь статическим ? 

Цитата(Incinerated @  18.2.2009,  14:48 Найти цитируемый пост)
смысл такой, если к серверу по заданному ай-пи и порту нельзя подключится, то нужно вернуть NULL при создании экземпляра данного класса. 


хотя, имхо, конструкция не очень удачная...

Автор: SenkraD 19.2.2009, 10:13
Цитата(Dem_max @  19.2.2009,  09:36 Найти цитируемый пост)
кстати незаметил, а зачем ты Create(char* ip,DWORD port); делаешь статическим ?
Я так полагаю что  это паттерн фабричный метод.
Тогда измени свой метод так:
Код

TWorkWithServer* TWorkWithServer::Create(char* ip,DWORD port){
TWorkWithServer* newServer = new TWorkWithServer();
try
{
    if(!WSAStartup(0x0202,&newServer->wsaData))
    {
          throw;
    }
    
    if((newServer->sServer = socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
    {
         throw;
    }
  
    newServer->InetAddr.sin_family      = AF_INET;
    newServer->InetAddr.sin_addr.s_addr = inet_addr(ip);
    newServer->InetAddr.sin_port        = htons(port);
    if(!connect(newServer->sServer,(struct sockaddr *)&newServer->InetAddr,sizeof(InetAddr)) != SOCKET_ERROR)
    {
         throw;
    }
} catch (...)
{
        delete newServer;
        newServer = NULL;
}
return newServer;


Плюс ексепшины можен нормальные кидать и обрабатывать их
Ну и ещё можно было бы часть переделать, но это уже думай сам

Автор: Incinerated 19.2.2009, 11:15
всем спасибо, а еще вопрос.... возможно ли такое сделать без отдельной функции Create? Чтобы где то в коде через new создавался экземпляр класса и если что-то не так в конструкторе, то возвращался бы NULL? Или только таким способом можно?
Спасибо.

Автор: mes 19.2.2009, 11:23
Цитата(Incinerated @  19.2.2009,  10:15 Найти цитируемый пост)
возможно ли такое сделать без отдельной функции Create? Чтобы где то в коде через new создавался экземпляр класса и если что-то не так в конструкторе, то возвращался бы NULL? 

нет, только разгрузив внешней (по отношению к создаваемому объекту) функцией. 

только вот Вы абсолютно уверены, что в случае отсутствия связи должен возвращаться NULL вместо объекта-сервера ?  

Автор: GSasha 19.2.2009, 12:17
Код

operator new

Автор: Incinerated 19.2.2009, 12:44
Цитата(mes @ 19.2.2009,  10:23)
только вот Вы абсолютно уверены, что в случае отсутствия связи должен возвращаться NULL вместо объекта-сервера ?

да. А зачем мне объект-сервер, если он ничего сделать не может?!

Автор: Dem_max 19.2.2009, 12:48
а в друг в данный момент коннекта нету, а через секунду сервер ответит. Так что лучше создавать экземпляр класса как обычно и иметь функцию Connect

Автор: Incinerated 19.2.2009, 13:08
Цитата(Dem_max @ 19.2.2009,  11:48)
а в друг в данный момент коннекта нету, а через секунду сервер ответит. Так что лучше создавать экземпляр класса как обычно и иметь функцию Connect

я так и сделал smile, просто я для себя, для развития, тему создал smile не знал можно ли и как если можно

Автор: SenkraD 19.2.2009, 15:30
Incinerated, для того чтобы сообщить об ошибки в конструкторе есть исключения
(кстати, это основная причина ввода исключений в С++)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)