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

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

ただいまの
回答率

90.12%

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

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 429

cho5

score 10

前提・実現したいこと

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

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

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

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

該当のソースコード

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

DetaImport.h

#pragma once
#include <string.h>
#include <iostream>
#include <string>
#include <deque>
#include <fstream>
#include <sstream> 

using namespace std;

//ファイル読み込みクラス
namespace funcBasic {

    ref class DataImport
    {
    private:
        deque<string> m_array;
    public:
        DataImport();
                AddDeque();
    };
}

DataImport.cpp

#include "DataImport.h"

using namespace funcBasic;

DataImport::DataImport()
{
}

void DataImport::AddDeque()
{
   this->m_array.push_back('a');
}

試したこと

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

deque<string> *m_array;

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

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

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

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

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+1

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

deque<string> *m_array;

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

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

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


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

namespace funcBasic {

    ref class DataImport
    {
    private:
        deque<string>* m_array;
    public:
        DataImport()
        {
            //newするのは一つだけ!2つ以上したくなったらdeque<string>をクラス分け!
            m = new deque<string>();
        }
        !DataImport()
        {
            if (m != nullptr)
                delete m;
            m = nullptr;
        }
        ~DataImport()
        {
            this->!DataImport();
        }
    };
}

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

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

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

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

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/22 12:39 編集

    結論: OpenCVSharpの開発者のブログを隅から隅まで読みましょう
    http://schima.hatenablog.com

    C++単体はだいぶかけるようになった自信あるけど、とてもじゃないけどC++/CLIとかやる気にならない。というかアロケータ作るとかやりたくない。

    キャンセル

  • 2019/02/22 12:43

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

    キャンセル

  • 2019/02/22 14:44

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

    キャンセル

+1

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

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

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

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

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

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/22 14:43

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

    キャンセル

  • 2019/02/22 20:15

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

    キャンセル

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 14:43

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

    キャンセル

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

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