【发布时间】:2017-06-29 15:05:58
【问题描述】:
我有一个由一些逻辑 + 底层系统调用组成的方法。现在必须实现另一种包含完全相同逻辑但仅更改底层系统调用的方法。
我正在尝试想办法重用公共代码并实现另一种方法,该方法可能需要一个可调用对象来调用底层系统调用,但由于 read 和 recv 调用的空灵性而没有成功不一样。
如果能找到一个相同的优雅解决方案,那就太好了。这些方法看起来像 -
第一个函数
std::string Socket::read(const int bufSize) const
{
auto buffer = std::make_unique<char[]>(bufSize + 1);
auto recvd = 0, count = 0;
std::string str;
str.reserve(bufSize);
do {
// ONLY THIS PART IS DIFFERENT
recvd = ::read(sockfd, buffer.get() + count, bufSize - count);
// ONLY THIS PART IS DIFFERENT
count += recvd;
if (count == bufSize) {
str.append(buffer.get());
str.reserve(str.length() + bufSize);
std::memset(buffer.get(), 0, bufSize);
count = 0;
}
} while (recvd > 0);
str.append(buffer.get(), count);
if (recvd == -1) {
// TODO: Check for recvd == EAGAIN or EWOULDBLOCK and
// don't throw exception in that case.
throw std::runtime_error("Error occurred while writing message");
}
return str;
}
第二个功能
std::string Socket::recv(const int bufSize, SF::recv flags) const
{
auto buffer = std::make_unique<char[]>(bufSize + 1);
auto recvd = 0, count = 0;
std::string str;
str.reserve(bufSize);
do {
// ONLY THIS PART IS DIFFERENT
const auto f = static_cast<int>(flags);
recvd = ::recv(sockfd, buffer.get() + count, bufSize - count, f);
// ONLY THIS PART IS DIFFERENT
count += recvd;
if (count == bufSize) {
str.append(buffer.get());
str.reserve(str.length() + bufSize);
std::memset(buffer.get(), 0, bufSize);
count = 0;
}
} while (recvd > 0);
str.append(buffer.get(), count);
if (recvd == -1) {
// TODO: Check for recvd == EAGAIN or EWOULDBLOCK and
// don't throw exception in that case.
throw std::runtime_error("Error occurred while writing message");
}
return str;
}
【问题讨论】:
-
你能解释一下代码应该做什么吗?我得到了基本要点,但我认为可能有更简单和更短的方法来实现这两者。
-
虽然我应该提一下,简单的方法是将函数逻辑简单地拆分为不同的函数。没有什么惊天动地的。
-
@tambre 从
<sys/socket.h> socket读取并返回std::string。 -
@AbhinavGauniyal 如果您已经有工作代码,那么要求改进和重构的更好地方可能是SE Code Review。
-
推荐阅读帮助页面,在发布前询问代码审查问题,并确保您符合他们的规则,否则您可能会在这里被退回。
标签: c++ networking refactoring c++14 code-reuse