Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
#define MEM_FN(x) boost::bind(&self_type::x, shared_from_this())
#define MEM_FN1(x,y) boost::bind(&self_type::x, shared_from_this(),y)
#define MEM_FN2(x,y,z) boost::bind(&self_type::x, shared_from_this(),y,z)
int i = 0;
label:
// code
if (++i < 100)
goto label;
void on_read(const error_code & err, size_t bytes)
{
if ( err) stop();
if ( !started() ) return;
std::string msg(read_buffer_, bytes);
if ( msg.find("login ") == 0) on_login(msg);
else if ( msg.find("ping") == 0) on_ping();
else if ( msg.find("ask_clients") == 0) on_clients();
}
void on_clients()
{
std::string msg;
for(array::const_iterator b =clients.begin(),e =clients.end(); b != e; ++b)
msg += (*b)->username() + " ";
do_write("clients " + msg + "\n");
}
msg += (*b)->username() + " "; является телом цикла. Ведь даже отступа нет. void read_answer()
{
already_read_ = 0;
read(sock_, buffer(buff_),
boost::bind(&talk_to_svr::read_complete, this, _1, _2));
process_msg();
}
typedef std::vector<client_ptr> array;
array clients;
array, который на самом деле vector? Это ведь разные типы данных, один динамический массив, другой использует память на стеке. Кстати говоря, члены класса talk_to_client: char read_buffer_[max_msg];
char write_buffer_[max_msg];
boost::array<char, max_msg> read_buffer_;
boost::array<char, max_msg> write_buffer_;
Примерно такими же соображениями руководствовался программист, сделавший в где-то в WinAPI макрос с именем max и мне уже много лет приходится писать #ifdef max\n#undef max\n#endif.
void on_read(const error_code & err, size_t bytes)
{
if (err)
{
stop();
}
else if (started())
{
const std::string msg(read_buffer_, bytes);
static const char* login("login ");
static const char* ping("ping");
static const char* ask_clients("ask_clients");
if (msg.compare(0, _countof(login) - 1, login) == 0)
{
on_login(msg);
}
else if (msg.compare(0, _countof(ping) - 1, ping) == 0)
{
on_ping();
}
else if (msg.compare(0, _countof(ask_clients) - 1, ask_clients) == 0)
{
on_clients();
}
}
}
static const char* login = "login ";
static const size_t login_size = _countof(login) - 1;
if (bytes > login_size && memcmp(read_buffer_, login, login_size) == 0)
...
else if (bytes == ping_size && memcmp(read_buffer_, ping, ping_size) == 0)
это ещё один привет из C++03.typedef std::vector<client_ptr> array;
Кстати говоря, члены класса talk_to_client:
char read_buffer_[max_msg]; char write_buffer_[max_msg];
должны быть объявлены вот так:
boost::array<char, max_msg> read_buffer_; boost::array<char, max_msg> write_buffer_;
Ну и все остальное в том же духе. Конечно кому-то кажется, что человек может писать так, как ему хочется. Использовать макросы и goto, привидение типов в стиле C, free и delete вместо RAII… Надо проработать программистом не один год и в разных командах, чтобы осознать важность этих правил.
Вообще то WinAPI, как и огромное количество другого системного кода, это C, а не C++, а стало быть наличие там данных макросов — нормальная ситуация.
Пусть код со скобками для меня привычнее, но это нисколько не мешает воспринять условия в исходном примере кода с однострочными ифами — так очень многие пишут.
С void on_clients() скорее согласен, отступ там желателен, но почему бы не сообщить о таком допущении в личку?
Ситуация с
typedef std::vector<client_ptr> array;
это ещё один привет из C++03.
#include <boost/array.hpp>
...
boost::array<char, 1024> data_;
Пожалуй соглашусь только с привидением типов в стиле C при использовании в C++, а вот всё остальное: макросы, goto, и сырые указатели использовать можно если это действительно необходимо.
p.s: руководствуясь написанным у Вас в пункте 3 вообще не понимаю зачем было писать что либо в данном топике, если данная тема Вам не интересна.
«Boost.Asio C++ Network Programming». Глава 4: Клиент и Сервер