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

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

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

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

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

Q&A

解決済

3回答

849閲覧

c++のクラスメンバにdequeを指定したい

cho5

総合スコア16

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

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

0グッド

1クリップ

投稿2019/02/22 00:40

前提・実現したいこと

vc++クラスのメンバーにdequeを指定して、同クラスのメソッドでdequeに値を追加したいのですが、
何かスマートな方法はあるのでしょうか。

ある程度調べましたが、自分の力ではどうにもならず、お力添えを頂けると幸いです。

発生している問題・エラーメッセージ

重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー C4368 'm_array' をマネージド 'funcBasic::DataImport' のメンバーとして定義できません。混合型はサポートされていません

該当のソースコード

質問用にかなりのコードを省略しています。

DetaImport.h

c++

1#pragma once 2#include <string.h> 3#include <iostream> 4#include <string> 5#include <deque> 6#include <fstream> 7#include <sstream> 8 9using namespace std; 10 11//ファイル読み込みクラス 12namespace funcBasic { 13 14 ref class DataImport 15 { 16 private: 17 deque<string> m_array; 18 public: 19 DataImport(); 20 AddDeque(); 21 }; 22}

DataImport.cpp

c++

1#include "DataImport.h" 2 3using namespace funcBasic; 4 5DataImport::DataImport() 6{ 7} 8 9void DataImport::AddDeque() 10{ 11 this->m_array.push_back('a'); 12}

試したこと

こちらを宣言したところ、ビルドは通ったのですが、

c++

1deque<string> *m_array; 2

Dequeに追加するタイミングで以下のようなエラーが出ます

重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー C2228 '.push_back' の左側はクラス、構造体、共用体でなければなりません

補足情報(FW/ツールのバージョンなど)

Visual C++
Visual Studio 2017
CLRプロジェクト

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

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

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

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

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

guest

回答3

0

エラーコード「C4368」でググるとそれなりの情報が上位に出てくるのですが、それらをもう少し試して見れば良いのです。

https://www.atmarkit.co.jp/fdotnet/special/vcppinvista01/vcppinvista01_03.html

しかし、これをビルドすると次のようなエラーが報告されます。

error C4368: 'counter_' をマネージ 'CounterLib' のメンバとして
定義できません。混合型はサポートされていません
VS 2005のエラー一覧に表示されるエラー
残念ながらマネージ・コードのクラスが、そのメンバにネイティブ・コードのクラスを持つことは許されていません。

と解説されています。実装例もあるので、そちらを参照すればオブジェクト生成から呼び出しや解放まで一連のコードがわかります。

投稿2019/02/22 01:15

t_obara

総合スコア5488

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

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

cho5

2019/02/22 05:43

参考にさせていただきます。ありがとうございます。
episteme

2019/02/22 11:15

そーいや書いたわソレ。 古文書の発掘ありがとさまです。
guest

0

ベストアンサー

うへぇ、C++/CLIだ、逃げろ~(違う

cpp

1deque<string> *m_array;

として定義したのであれば、使う側は

cpp

1void DataImport::AddDeque() 2{ 3 this->m_array->push_back('a'); 4}

となるんじゃないでしょうかね?


C++/CLIが嫌いすぎて脳みそから消去してた内容をググって回復したので追記。

cpp

1namespace funcBasic { 2 3 ref class DataImport 4 { 5 private: 6 deque<string>* m_array; 7 public: 8 DataImport() 9 { 10 //newするのは一つだけ!2つ以上したくなったらdeque<string>をクラス分け! 11 m = new deque<string>(); 12 } 13 !DataImport() 14 { 15 if (m != nullptr) 16 delete m; 17 m = nullptr; 18 } 19 ~DataImport() 20 { 21 this->!DataImport(); 22 } 23 }; 24}

コンストラクタでnewした上で!DataImportと~DataImport (C#でいうデストラクタとDispose)を実装します。

ところが問題があって、そもそもstd::dequeの内部で行われるメモリー確保が.NETのGCで検知されないため、このままだとメモリーがなかなか開放されないということが起こります。つまりアロケータを作るわけですね。

でアロケータをバグなく作るとか本当に無理ゲーなのでやりたくないわけです。なんならOpenCVSharp作った人も本番実装に入れてないわけです。つまりなかなかメモリが開放されない問題は諦めたわけですね。まあC#側ではusingブロックだっけかできちんとDisposeしてもらうようにしろということですね。

で結論としてはそんな意味不明な苦労するんじゃなくてGeneric::Listとかを最初から使うのがいいんじゃないですかね・・・

投稿2019/02/22 00:45

編集2019/02/22 04:02
yumetodo

総合スコア5850

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

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

stdio

2019/02/22 00:52

そして解放を忘れて、えらい目にあう落ちが(違
yumetodo

2019/02/22 01:29

いっそgcnewするべきか?(これだからC++/CLIは
cho5

2019/02/22 02:15

ありがとうございます。無事コンパイルが通りました。 初歩的な質問で申し訳ないのですが、gcnewを用いる場合はどういうかきかたをすればよいのでしょうか。
stdio

2019/02/22 02:52

C++/CLIを悪みたいにつぶやいてますが、そんなにC++/CLIって嫌いですか? すみません、私はその辺の話はうとくて... 多分私の知っているC++はMSVCの事だと思いますが....
yumetodo

2019/02/22 03:29

悪というよりC++と.NETの世界の両方に深い理解の必要な超上級者向け言語なので手を出したくないというか・・・ gcnewってのは deque<string>^ m_array; としておいてコンストラクタとかで this->m_array = gcnew deque<string>() とできなかったかなと思ったんですが http://telltale.hatenablog.com/entry/2016/07/13/222833 無理そうですね、はい。
yumetodo

2019/02/22 03:39

つまり http://schima.hatenablog.com/entry/2015/12/07/235645 でやっているように !DataImportと~DataImport (C#でいうデストラクタとDispose)を実装しないといけないわけですね、あとコンストラクタで複数のnewを書かないように、死にます。複数書きたくなった瞬間それを別クラスに切り出しましょう。RAII大事。
yumetodo

2019/02/22 03:42 編集

結論: OpenCVSharpの開発者のブログを隅から隅まで読みましょう http://schima.hatenablog.com C++単体はだいぶかけるようになった自信あるけど、とてもじゃないけどC++/CLIとかやる気にならない。というかアロケータ作るとかやりたくない。
yumetodo

2019/02/22 03:43

冗談抜きでC++/CLI側で用意されているListとかそのへん使うほうが楽だし安全だしいいと思います。むりやりSTLのコンテナを使うもんじゃない。
cho5

2019/02/22 05:44

貴重な情報を沢山ありがとうございました。 勉強になりました。
guest

0

こんにちは。

マネージド云々というエラーメッセージが出るということは、お使いの言語は C++ ではなくマイクロソフトがC++を独自に拡張した C++/CLI と思われます。

ちょっと調べてみたところ、下記が見つかりました。
How to: Wrap Native Class for Use by C#
C++/CLIでネイティブの構造体を使用したい

参照クラス(.NETのマネージド・クラス)は、C++ネイティブなクラス型のメンバ変数を直接持つことはできないそうです。(マネージドの中にアンマネージドを直接持つってかなり厄介でしょうから、禁止しているのでは?)


【余談ですが】
C++/CLIは、唯でさえ難しい C++ を超拡張しています。しかも、C#(というか.NET)の膨大なライブラリが使えます。(C++/CLIを使う目的の多くが.NETのライブラリを使うことでしょう。)
そして、C#や標準C++の情報は多いですが、C++/CLI(特にあいのこ部分)の情報は少ないです。
(でも、検索していてC++/CLI入門というサイトがヒットしました。有用そうな感じです。)

ですので、C++とC#の両方をそれなりに高いレベルでマスターした上で、あいのこ部分の使い方をそれなりに学習する必要があります。状況が許すのであれば標準のC++を使った方が開発効率は上がると思いますよ。

投稿2019/02/22 02:43

Chironian

総合スコア23272

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

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

cho5

2019/02/22 05:43

貴重なご意見ありがとうございます。 標準のC++が使用できないか検討してみることにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問