📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
| (同じ利用者による、間の4版が非表示) | |||
| 79行目: | 79行目: | ||
// C++14以降であれば、make_unique関数を使うこともできる | // C++14以降であれば、make_unique関数を使うこともできる | ||
std::unique_ptr<int> ptr3=std::make_unique<int>(10); | std::unique_ptr<int> ptr3=std::make_unique<int>(10); | ||
</ | </syntaxhighlight> | ||
<br> | <br> | ||
< | <syntaxhighlight lang="c++"> | ||
// unique_ptr<T>は、コピーは禁止されているが、move関数は使用することができる。 | // unique_ptr<T>は、コピーは禁止されているが、move関数は使用することができる。 | ||
std::unique_ptr<int> ptr(new int(10)); | std::unique_ptr<int> ptr(new int(10)); | ||
| 121行目: | 121行目: | ||
// unique_ptr<T[]>のように指定すれば、配列を扱うこともできる | // unique_ptr<T[]>のように指定すれば、配列を扱うこともできる | ||
// 配列型の場合、operator[](size_t)を使用することができる | // 配列型の場合、operator[](size_t)を使用することができる | ||
// int型配列の要素数10を宣言 | |||
std::unique_ptr<int[]> ptrArray(new int[10]); | std::unique_ptr<int[]> ptrArray(new int[10]); | ||
// または | |||
std::unique_ptr<int[]> ptrArray = std::make_unique<int[]>(10); | |||
for(int i = 0; i < 10; i++) | for(int i = 0; i < 10; i++) | ||
| 198行目: | 201行目: | ||
これは、オブジェクトの生成・破棄に比べれば遥かに軽い操作であるが、スレッドセーフにするために排他されていたりもするので0ではない。<br> | これは、オブジェクトの生成・破棄に比べれば遥かに軽い操作であるが、スレッドセーフにするために排他されていたりもするので0ではない。<br> | ||
<br><br> | <br><br> | ||
== std::vectorクラスとの比較 == | |||
<code>std::vector</code>クラスと<code>std::unique_ptr</code>クラスにおいて、両方のアプローチにはそれぞれ利点がある。<br> | |||
<br> | |||
* std::vectorを使用する方法 | |||
*: サイズの動的な変更が容易である。 | |||
*: STLアルゴリズムとの互換性が高い。 | |||
*: メモリ割り当てと解放が自動的に行われる。 | |||
*: <br> | |||
* std::unique_ptrを使用する方法 | |||
*: 生の配列に近い性能を維持しつつ、安全なメモリ管理が可能である。 | |||
*: サイズが固定の場合に適している。 | |||
<br> | |||
どちらの方法も、以前の実装と比べてメモリリークのリスクが低く、より現代的なC++のスタイルに則っている。<br> | |||
プロジェクトの要件や好みに応じて、適切な方法を選択すること。<br> | |||
<br> | |||
<code>std::vector</code>クラスを使用する方法は、より柔軟性が高く、一般的に推奨される。<br> | |||
一方で、<code>std::unique_ptr</code>クラスを使用する方法は、パフォーマンスが重要で、配列サイズが固定の場合に適している。<br> | |||
<br> | |||
==== 例 : Linuxのグループの取得 ==== | |||
<syntaxhighlight lang="c++"> | |||
#include <iostream> | |||
#include <vector> | |||
#include <string> | |||
#include <cstring> | |||
#include <sstream> | |||
#include <memory> | |||
#include <grp.h> | |||
#include <pwd.h> | |||
#include <unistd.h> | |||
#include <sys/types.h> | |||
#include <errno.h> | |||
std::vector<std::string> getUserGroups(std::string& errorMessage) | |||
{ | |||
std::vector<std::string> groups; | |||
errorMessage.clear(); | |||
uid_t uid = getuid(); | |||
struct passwd *pw = getpwuid(uid); | |||
if (!pw) { | |||
std::stringstream ss; | |||
ss << "Failed to get user info: " << strerror(errno); | |||
errorMessage = ss.str(); | |||
return groups; | |||
} | |||
int ngroups = 0; | |||
if (getgrouplist(pw->pw_name, pw->pw_gid, nullptr, &ngroups) == -1) { | |||
errorMessage = "Failed to get group list size"; | |||
return groups; | |||
} | |||
if (ngroups > 0) { | |||
auto gids = std::make_unique<gid_t[]>(ngroups); | |||
if (getgrouplist(pw->pw_name, pw->pw_gid, gids.get(), &ngroups) == -1) { | |||
errorMessage = "Failed to get group list"; | |||
return groups; | |||
} | |||
for (int i = 0; i < ngroups; i++) { | |||
errno = 0; | |||
struct group *gr = getgrgid(gids[i]); | |||
if (gr) { | |||
groups.push_back(gr->gr_name); | |||
} | |||
else { | |||
std::cerr << "Failed to get group name for gid " << gids[i] << ": " << strerror(errno) << std::endl; | |||
} | |||
} | |||
} | |||
else { | |||
errorMessage = "User is not a member of any groups"; | |||
} | |||
return groups; | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C++]] | [[カテゴリ:C++]] | ||