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

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

ただいまの
回答率

88.93%

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 315

hamusuke

score 3

問題

例のようにスマートポインタ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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+1

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

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

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

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

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/19 18:06

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

    キャンセル

  • 2020/07/19 18:13

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

    キャンセル

  • 2020/07/19 18:16

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

    キャンセル

  • 2020/07/19 21:42

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

    キャンセル

checkベストアンサー

0

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

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

#include <iostream>
#include <memory>

int main(){
    constexpr unsigned int size = 5;//要素数

    auto mem1 = std::shared_ptr<int[]>(new int[size]);
    auto mem2 = std::shared_ptr<int[]>();

    for(int i=0;i<size;i++)mem1[i] = i;//mem1へ数値代入

    mem2 = mem1;//shared_ptrならコピーできる

    for(int i=0;i<size;i++)std::cout << mem2[i] << std::endl;//mem2の内容表示

    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/19 21:39

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

    キャンセル

  • 2020/07/20 05:36 編集

    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

    キャンセル

  • 2020/07/20 17:57

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

    キャンセル

0

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/20 17:52

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

    キャンセル

  • 2020/07/20 18:26

    やりたいことが本当に
    「GpuMat型(が保有する何らかの値)のコピーを作ること」ではなくて,
    「単一のGpuMat型を参照する複数個のshared_ptrを作ること」なのか?
    というのが,こちらにはわかりませんが…
    (少なくとも,質問文に提示されているコードの形でコピーを作る意味がどこにあるのかさっぱりわからない)

    元々 unique_ptr であったならば,それ相応の理由があったのでは…?
    単にその型を shared_ptr に変えた「だけ」ならば,動作に差は見られないでしょうけど,
    問題は,あなたが作った「コピー」を実際に何かしら使い始めたときに(つまり,これから)生じるかもしれません.

    キャンセル

  • 2020/07/20 18:37 編集

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

    キャンセル

  • 2020/07/20 18:55

    以下のような疑問がわきますが… まぁとにかく注意深くやればよいと思います.(返信的なものは不要です)

    疑問:(GpuMatを使ったことが無いので,この疑問自体が間違っているかもですが)
    それは,複製をつくらずにそのまま元のunique_ptr経由で「別の処理を適用」することとは異なる話になっているのだろうか…?

    ・なっていない場合(すなわち,結局同一のGPU上のメモリ(?)をいじくっているのだとしたら) → だったらコピーを作る意味は無いような?

    ・なっている場合(「コピー」が元とは別のGPU上メモリをいじくるようにコピー後に何か適切な処理をするハズ) → 無理にコピーから出発(?)せずとも,新たなGpuMatインスタンスを作るところから出発するのが素直だったりしないのか?

    キャンセル

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

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る