私はいくつかのロジック+基本システムコールで構成されたメソッドを持っています。まったく同じロジックを含み、基盤となるシステムコールの変更だけを含むもう1つの方法を実装する必要があります。は、同じような関数定義の重複コードを排除します。
共通のコードを再利用する方法を考えています。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
簡単な方法は、関数ロジックを異なる関数に分割することです。何も地球を破壊するものではない。 – tambre
@tambreは ' socket'から読み込み、' std :: string'を返します。 –