C++ - jak to lze udělat lépe?

dword

C++ - jak to lze udělat lépe?
« kdy: 23. 08. 2016, 11:11:29 »
Ahoj všem, učím se C++, ale nějak cítím že to není ono a hledám inspiraci jak to udělat lépe.

Kód: [Vybrat]
/* obsluhovač všech socketů */
class SocketDispatcher
{
  static std::vector<Socket *> sockets;
  ...
};

/* třída se socketem, umožnující volat callback při příjmu dat */
class Socket
{
  void (*cb)(void*, Socket*, void*, size_t) = NULL;
  void *cb_param = NULL;
  ...
}

/* parser příchozích dat JSON protokolu */
class jproto {
  void fetch(void *data, size_t len);
  bool process(Json::Value &out);
  ...
};

/* třída s klientem, konstruktor nastaví callbacky, receive_msg příjme data, zparsuje pomocí třídy jproto a poté předá funkci process_msg() */
class client
{
  jproto parserů
  client(char *ip, uint16_t port, double period);
  void receive_msg(void* obj, Socket* s, void* data, size_t len);
  void process_msg(Socket* s, Json::Value& msg);
  ...
}

client::client(char *ip, uint16_t port, double period) : ip(ip), port(port), period(period)
{
uint32_t addr = inet_addr(ip);
s = new Socket(addr, port, PROTO_TCP, true);
if(s->is_valid())
{
s->set_receiver(receive_msg, this);
SocketDispatcher sd;
sd.get()->add(s);
}
}

void client::receive_msg(void* obj, Socket* s, void* data, size_t len)
{
eluclient *_this = (eluclient *) obj;
_this->parser.fetch(data, len);

Json::Value msg;
while(_this->parser.process(msg))
_this->process_msg(s, msg);
}

Funguje to jak jsem chtěl, ale chtěl bych se vyhnout "_this", a také bych případně chtěl vědět, jak napsat callback v třídě Socket tak, aby jsem mohl volat nestatickou členskou metodu jakékoliv třídy. Díky za rady


dword

Re:C++ - jak to lze udělat lépe?
« Odpověď #1 kdy: 23. 08. 2016, 11:18:23 »
sorry, řádek:
Kód: [Vybrat]
eluclient *_this = (eluclient *) obj;má být takhle:
Kód: [Vybrat]
client *_this = (client *) obj;

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:C++ - jak to lze udělat lépe?
« Odpověď #2 kdy: 23. 08. 2016, 11:34:28 »
Ahoj všem, učím se C++, ale nějak cítím že to není ono a hledám inspiraci jak to udělat lépe.

Kód: [Vybrat]
/* obsluhovač všech socketů */
class SocketDispatcher
{
  static std::vector<Socket *> sockets;
  ...
};

/* třída se socketem, umožnující volat callback při příjmu dat */
class Socket
{
  void (*cb)(void*, Socket*, void*, size_t) = NULL;
  void *cb_param = NULL;
  ...
}

/* parser příchozích dat JSON protokolu */
class jproto {
  void fetch(void *data, size_t len);
  bool process(Json::Value &out);
  ...
};

/* třída s klientem, konstruktor nastaví callbacky, receive_msg příjme data, zparsuje pomocí třídy jproto a poté předá funkci process_msg() */
class client
{
  jproto parserů
  client(char *ip, uint16_t port, double period);
  void receive_msg(void* obj, Socket* s, void* data, size_t len);
  void process_msg(Socket* s, Json::Value& msg);
  ...
}

client::client(char *ip, uint16_t port, double period) : ip(ip), port(port), period(period)
{
uint32_t addr = inet_addr(ip);
s = new Socket(addr, port, PROTO_TCP, true);
if(s->is_valid())
{
s->set_receiver(receive_msg, this);
SocketDispatcher sd;
sd.get()->add(s);
}
}

void client::receive_msg(void* obj, Socket* s, void* data, size_t len)
{
eluclient *_this = (eluclient *) obj;
_this->parser.fetch(data, len);

Json::Value msg;
while(_this->parser.process(msg))
_this->process_msg(s, msg);
}

Funguje to jak jsem chtěl, ale chtěl bych se vyhnout "_this", a také bych případně chtěl vědět, jak napsat callback v třídě Socket tak, aby jsem mohl volat nestatickou členskou metodu jakékoliv třídy. Díky za rady
Používání raw pointerů je zlo.

dword

Re:C++ - jak to lze udělat lépe?
« Odpověď #3 kdy: 23. 08. 2016, 11:43:42 »
zboj: nijak jsi mi neporadil, a tvůj názor je subjektivní, pokud nemáš nic k věci, už sem prosím nepiš

gamer

Re:C++ - jak to lze udělat lépe?
« Odpověď #4 kdy: 23. 08. 2016, 12:08:45 »
Co třeba něco takového?
Kód: [Vybrat]
#include <vector>
#include <iostream>
#include <functional>

class Socket
{
public:
    std::function<void(const char*, size_t)> callback;

    void receive(const char* data, size_t count)
    {
        callback(data, count);
    }
};

class Client1
{
public:
    void process(const char* data, size_t count)
    {
        std::string str(data, count);
        std::cout << "client1: " <<  data << std::endl;
    }
};

class Client2
{
public:
    void process(const char* data, size_t count)
    {
        std::string str(data, count);
        std::cout << "client2: " <<  data << std::endl;
    }
};

int main()
{
    Client1 client1;
    Client2 client2;

    std::vector<Socket> sockets;
    sockets.emplace_back();
    sockets.back().callback = std::bind(&Client1::process, client1, std::placeholders::_1, std::placeholders::_2);
    sockets.emplace_back();
    sockets.back().callback = std::bind(&Client2::process, client2, std::placeholders::_1, std::placeholders::_2);

    std::string data1("DATA1");
    sockets[0].receive(data1.data(), data1.size());

    std::string data2("DATA2");
    sockets[1].receive(data2.data(), data2.size());
}


borekz

  • ****
  • 476
    • Zobrazit profil
    • E-mail
Re:C++ - jak to lze udělat lépe?
« Odpověď #5 kdy: 23. 08. 2016, 12:09:09 »
Máš nějaký důvod pro upřednostnění callbacku před virtuální metodou nebo lambda funkcí ?

Tuxik

  • *****
  • 1 473
    • Zobrazit profil
    • E-mail
Re:C++ - jak to lze udělat lépe?
« Odpověď #6 kdy: 23. 08. 2016, 12:22:26 »
Promiň, moc konstruktivní taky nebudu, ale opravdu to není úplně ono... Celý mi to přijde nějaký moc překombinovaný, přepointerovaný a po pravdě zralý na "znovu a lépe". Zboj má s těma pointerama pravdu, já osobně to vidím jako C násilně přešpagetovaný do C++ s použitím OOP za každou cenu...

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:C++ - jak to lze udělat lépe?
« Odpověď #7 kdy: 23. 08. 2016, 12:33:01 »
zboj: nijak jsi mi neporadil, a tvůj názor je subjektivní, pokud nemáš nic k věci, už sem prosím nepiš
To není názor a není subjektivní, to je základní pravidlo, které ti buď někdo řekne, nebo se ho bolestně naučíš za chodu. Jak píše kolega výše, ten kód je otřesný, u zkoušky na VŠ bys neprošel, chce to nejdříve se C++ aspoň trochu naučit, než v něm budeš něco psát, takto jen ztrácíš čas svůj i těch, co s tím kódem budou mít kdy do činění. Máš jen dvě možnosti, buď to cele přepíšeš od nuly tak, aby to aspoň na první pohled vypadalo jako rozumný kód v C++, nebo - což je mnohem lepší volba - si pořídíš nějakou elementární knihu o C++ a naučíš se aspoň základy, než se znovu o něco pokusíš.

dword

Re:C++ - jak to lze udělat lépe?
« Odpověď #8 kdy: 23. 08. 2016, 12:38:41 »
gamer: díky, tohle jsem potřeboval

téma uzavřeno

Inkvizitor

Re:C++ - jak to lze udělat lépe?
« Odpověď #9 kdy: 23. 08. 2016, 13:05:59 »

dword

Re:C++ - jak to lze udělat lépe?
« Odpověď #10 kdy: 23. 08. 2016, 13:43:23 »
téma uzavřeno

Fakt?

Samozřejmě mluvím pouze za sebe, a ano, opravdu! Dostal jsem, pro co jsem tu přišel.

D3ad

Re:C++ - jak to lze udělat lépe?
« Odpověď #11 kdy: 23. 08. 2016, 14:54:21 »
téma uzavřeno

Fakt?

Samozřejmě mluvím pouze za sebe, a ano, opravdu! Dostal jsem, pro co jsem tu přišel.

Povedla se ti uzasna vec. Vlakno na foru, ktere se nezvrtlo v trolleni maximalniho kalibru.

Tuxik

  • *****
  • 1 473
    • Zobrazit profil
    • E-mail
Re:C++ - jak to lze udělat lépe?
« Odpověď #12 kdy: 23. 08. 2016, 14:58:45 »
téma uzavřeno

Fakt?

Samozřejmě mluvím pouze za sebe, a ano, opravdu! Dostal jsem, pro co jsem tu přišel.

Povedla se ti uzasna vec. Vlakno na foru, ktere se nezvrtlo v trolleni maximalniho kalibru.
A přitom to po pořádným trollingu přímo volalo :D

D3ad

Re:C++ - jak to lze udělat lépe?
« Odpověď #13 kdy: 23. 08. 2016, 15:31:47 »
téma uzavřeno

Fakt?

Samozřejmě mluvím pouze za sebe, a ano, opravdu! Dostal jsem, pro co jsem tu přišel.

Povedla se ti uzasna vec. Vlakno na foru, ktere se nezvrtlo v trolleni maximalniho kalibru.
A přitom to po pořádným trollingu přímo volalo :D

Pravda, cekal jsem letajici lopaty apod.

Jeste neni pozde, co si myslis o letosni sklizni mrkve?

cppman

Re:C++ - jak to lze udělat lépe?
« Odpověď #14 kdy: 23. 08. 2016, 15:38:57 »
Citace
co si myslis o letosni sklizni mrkve?

Dword je taková lopata, že by se s ním dala sklízet mrkev. 8)