質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

2806閲覧

スマートポインタの値を他のスマートポインタにコピーしたい

hamusuke

総合スコア4

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/07/19 08:29

編集2020/07/19 09:07

###問題
例のようにスマートポインタtarget_cost_にある値を、goal_cost_に保存したいのですがスマートポインタのコピーはできないということでした。OpenCVのプログラムでスマートポインタを使用しているため、どうにかしてスマートポインタ間で値をコピーする方法がないかお聞きしたいです。
###例

class Hoge{ public: void Run(); private: void Loop(); std::unique_ptr<GpuMat<float>> target_cost_; // 元のポインタ  std::unique_ptr<GpuMat<float>> goal_cost_; //保存先にしたいポインタ ...

###備考
visual studio 2019

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

同時に2つの質問となってしましますがよろしくお願いいたします。

わかってると思いますが、質問は分けて欲しいですね。

例のようにprivateで定義した関数Loop()をpublic内の関数Run()で呼び出すことは不可能なのでしょうか。

Run の中で Loop を呼び出したいんですよね。できますよ。やってみましたか?

privateで定義したものはRunPrivate()のように同一のprivate内で定義した関数からしか呼び出せないと思っている

どうしてそう思ったのでしょうか。学ぶために使っている本などをもう一度見直してみるといいと思います。

投稿2020/07/19 08:50

編集2020/07/19 08:51
bboydaisuke

総合スコア5275

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hamusuke

2020/07/19 09:06

bboydaisuke様 ご指摘いただきありがとうございます。 privateメンバ関数の呼び出しについて勘違いをしてしまっておりました。勘違いをした状態で試さずに、スマートポインタの質問に合わせて記載してしまいました。privateでもclassないからであればアクセスが出来ると明記してあり、実際にアクセスできることを確認いたしました。 privateについての内容は本来の質問内容(スマートポインタ)とそぐわないため、削除させていただきます。
bboydaisuke

2020/07/19 09:13

そういうわけで問題はわけてほしいんですよね。私はちゃんと答えたのにその問題が解決済みにならない。私が答えた問題は本来の質問ではないと言われてしまう。Best Answer にもならない。これでは答える気もなくなります。
bboydaisuke

2020/07/19 09:16

teratail は答える側にその気にさせるような仕掛けを頑張って作っているのに、その仕掛けを無にするような質問の仕方をされると、答える人が去ってしまいます。 答える人がいない質問サイトにしてしまわないよう気をつけてください。
hamusuke

2020/07/19 12:42

bboydaisuke様 まずteratailにおける質問側のマナーや礼儀をよく考えるべきであるということを再確認いたしました。以後このようなことがないように注意させていただきたいと思います。ご回答、ご指摘いただきありがとうございました。
guest

0

本件の回答として不適切かもしれませんが,

GpuMat型自体が,参照カウントを管理している型である(std::shared_ptr相当)ようなので,
そもそもスマートポインタで管理する必要があるのか?という点から考えるべきように思います.

(まぁ,unique_ptr的な管理をしたい場面なのかもしれませんが)

投稿2020/07/20 02:07

fana

総合スコア11654

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hamusuke

2020/07/20 08:52

fana様 元々std::unique_ptrで定義されていたため、その明確な理由については分かりませんが、保存しているデータをかなりあっちこっちで変換したり呼び出しているため、unique_ptrで独占的に定義したのかな、と思っていました。試しにshared_ptrに定義を変更してみたところ、結果には今のところ悪影響が見られず、shared_ptrで定義して値をやり取りすることが出来ました。 fana様、diode様、bboydaisuke様のおかげで問題を解決することが出来ました。 ご回答いただきありがとうございました。
fana

2020/07/20 09:26

やりたいことが本当に 「GpuMat型(が保有する何らかの値)のコピーを作ること」ではなくて, 「単一のGpuMat型を参照する複数個のshared_ptrを作ること」なのか? というのが,こちらにはわかりませんが… (少なくとも,質問文に提示されているコードの形でコピーを作る意味がどこにあるのかさっぱりわからない) 元々 unique_ptr であったならば,それ相応の理由があったのでは…? 単にその型を shared_ptr に変えた「だけ」ならば,動作に差は見られないでしょうけど, 問題は,あなたが作った「コピー」を実際に何かしら使い始めたときに(つまり,これから)生じるかもしれません.
hamusuke

2020/07/20 09:38 編集

fana様 もともとunique_ptrで保存した値に対して変換処理を適用して、結果を出力するコードだったのですが、そこに別の変換処理を加えて別の結果を得ようと考えました。 そのためにunique_ptrの値を複製して、複製したものに別の処理を加えていこうとしていました。 いまは複製したshared_ptrに別の処理を適用して結果を出力していますが、特に問題はないように思えます。ですが後々なんらかの影響が起こりうる、ということも確かに注意しなければならないと思います。ご忠告ありがとうございます。
fana

2020/07/20 09:55

以下のような疑問がわきますが… まぁとにかく注意深くやればよいと思います.(返信的なものは不要です) 疑問:(GpuMatを使ったことが無いので,この疑問自体が間違っているかもですが) それは,複製をつくらずにそのまま元のunique_ptr経由で「別の処理を適用」することとは異なる話になっているのだろうか…? ・なっていない場合(すなわち,結局同一のGPU上のメモリ(?)をいじくっているのだとしたら) → だったらコピーを作る意味は無いような? ・なっている場合(「コピー」が元とは別のGPU上メモリをいじくるようにコピー後に何か適切な処理をするハズ) → 無理にコピーから出発(?)せずとも,新たなGpuMatインスタンスを作るところから出発するのが素直だったりしないのか?
guest

0

ベストアンサー

どうにかしてスマートポインタ間で値をコピーする方法がないかお聞きしたいです。

std::unique_ptrを使うのではなく
std::shared_ptrを使えばコピーできます。

c++

1#include <iostream> 2#include <memory> 3 4int main(){ 5 constexpr unsigned int size = 5;//要素数 6 7 auto mem1 = std::shared_ptr<int[]>(new int[size]); 8 auto mem2 = std::shared_ptr<int[]>(); 9 10 for(int i=0;i<size;i++)mem1[i] = i;//mem1へ数値代入 11 12 mem2 = mem1;//shared_ptrならコピーできる 13 14 for(int i=0;i<size;i++)std::cout << mem2[i] << std::endl;//mem2の内容表示 15 16 return 0; 17} 18 19

投稿2020/07/19 09:15

編集2020/07/19 09:33
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hamusuke

2020/07/19 12:39

diode様、コードを示して頂いてありがとうございます。いただいたコードを拝見いたしましたがshared_ptrを使用したほうが値のコピーを容易に使えるようですね。質問後にサイトを探し回っている中で次のようなサイトを見つけました。 https://qiita.com/hmito/items/db3b14917120b285112f こちらではmoveを使用して所有権を移動しているようですが、特に理由がなければdiode様の示されたように、shared_ptrを使用するほうがよさそうです。ありがとうございました。
退会済みユーザー

退会済みユーザー

2020/07/19 21:13 編集

hamusukeさん お返事ありがとうございます。 > こちらではmoveを使用して所有権を移動しているようですが、特に理由がなければdiode様の示されたように、shared_ptrを使用するほうがよさそうです moveしたあとの抜け殻は もう使えないですからね... あとstd::shared_ptrはコピーもムーブもできる 完全無欠の最強スマートポインタのように見えますが unique_ptrより処理速度が遅かったり https://wandbox.org/permlink/6a0ZqA5Sa2WGo0mo のように循環参照が発生したらメモリリークの原因になってしまうので 何も理由がないのならstd::shared_ptrを使うというのは あまりよろしくないかと思われます。 やはり優先的に使うべきはstd::unique_ptrで どうしてもコピーしたいならstd::shared_ptrを選び 循環参照が発生するならstd::weak_ptrを使うべきだと思います。 ↓std::weak_ptrを使用し循環参照下でもデストラクタを動かせるようにした例 https://wandbox.org/permlink/p5P8RpfMAJ4qD6KE
hamusuke

2020/07/20 08:57

diode様 頂いたURLへ飛んで実行してみました、ありがとうございます。 moveした後は元のunique_ptrは使えないということは初めて知りました。試してみたところ、確かに元ポインタの中の値を参照することはできませんでした。 diode様のおっしゃるように、shared_ptrを使用して値をやり取りしたところ正常に動作して目的を達成することが出来ました。ありがとうございました。 diode様から頂いたご回答を通して目的の達成だけではなく、unique,shared,weak_ptrについて詳細を知ることが出来ましたので、diode様のご回答をベストアンサーとさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問