C++/CLIでクラス内の要素を相互利用する方法

このQ&Aのポイント
  • C++/CLIでクラスの中に定義された構造体等を複数のクラス間で相互利用する方法について説明します。
  • クラス内で定義された要素を他のクラスで使用するためには、クラスの宣言を行う必要があります。
  • C++/CLIでは、クラス内の要素を相互に利用することが可能ですが、enumの場合には注意が必要です。
回答を見る
  • ベストアンサー

C++/CLIでクラス内の要素を相互利用する方法

C++/CLIでクラスの中に定義された構造体等を、複数のクラス間で相互利用したいのですが、そのようなことは可能なのでしょうか。 とりあえず以下のコードを見ていただきたいのですが、 ref class class1; ref class class2; ref class class1 { public:  enum struct enum1  {   aa,bb  };  void func1a(class1^ obj){} // 1. OK  void func2a(class2^ obj){} // 2. OK  void func1b(class1::enum1 e){} // 3. OK  void func2b(class2::enum2 e){} // 4. ERROR }; ref class class2 { public:  enum struct enum2  {   aa,bb  };  void func1a(class1^ obj){} // 5. OK  void func2a(class2^ obj){} // 6. OK  void func1b(class1::enum1 e){} // 7. OK  void func2b(class2::enum2 e){} // 8. OK }; これの4.がコンパイルエラーになります。 このような構造を定義することはできないのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

 こんばんは。  どうやら、無理な様です。  列挙体をクラスの外に出して一番上に書けば解決ですが、如何してもクラス内に置く事を死守するのであれば、「4」のメンバ関数をテンプレートにして、class2::enum2が見えている所でテンプレートの全特化を行えば出来ます。  以下参考程度になれば。 // clrconsole.cpp : メイン プロジェクト ファイルです。 #include"stdafx.h" using namespace System; ref class class1; ref class class2; ref class class1 { public: enum struct enum1 { aa,bb }; void func1a(class1^ obj){} // 1. OK void func2a(class2^ obj){} // 2. OK void func1b(class1::enum1 e){} // 3. OK template<class _Enum> void func2b(_Enum e);// 4. 中身を引っこ抜く }; ref class class2 { public: enum struct enum2 { aa,bb }; void func1a(class1^ obj){} // 5. OK void func2a(class2^ obj){} // 6. OK void func1b(class1::enum1 e){} // 7. OK void func2b(class2::enum2 e){} // 8. OK }; // 4. 中身 template<> void class1::func2b<class2::enum2>(class2::enum2 e) { //class2::enum2の時のみ } int main(array<System::String ^> ^args) { class1^ c = gcnew class1(); c->func2b(class2::enum2::aa); c->func2b(class2::enum2::bb); //適合しないenumを入れるとリンクエラーになる //c->func2b(class1::enum1::aa); //c->func2b(class1::enum1::bb); return 0; }

qwertfk
質問者

お礼

回答ありがとうございます。 やっぱり無理なんでしょうか... テンプレートを使うというのは思いつかなかったですが、そこまでするのであれば、個人的な好みでいえば void func2b(int e); c->func2b((int)class1::enum1::aa); のほうが良いかと思います。これだと普通のC++の型安全度と同じなので。

関連するQ&A

  • 派生クラスのメンバを基底クラスの参照に代入(C++

    文末のコードのように、 基底クラスで、派生クラスのメンバの参照を持つのはまずいでしょうか。 (classではなくstructにしているのは質問上でのpublic:の省略のためだけです) 初期化順序的には、基底クラスの参照先は、 基底クラスのコンストラクタが走る時点で初期化されていないので、 コンストラクタ内で参照に対して何かしようとすると問題になると思っています。 基底クラスのコンストラクタ内で派生クラスメンバの参照に対して何かしなければ、 参照は有効で、派生クラスのコンストラクタ実行後であれば 問題なく動くと思ってよいでしょうか。 struct A { int& m_ref; A(int& ref) : m_ref(ref) { } }; struct B : public A { int m_obj; B() : A(m_obj) { } };

  • C++ クラスをメンバにもつクラスについて

    お世話になります。C++初心者でうまくコードが書けません(><) クラス1と2があり、クラス1のメンバにはクラス2があります。 メインでクラス1をインスタンス化してクラス2のfunc2を呼び出します。 func2ではクラス1のインスタンスから呼び出された場合にクラス1の m_int1を取得します。 Class Class1{ public:  int m_int1;  Class2 m_Class2; }; Class Class2{ public: void func2(); }; void Class2::func2(){  /*ここの記述方法が分かりません*/  /*C1から呼び出されたらC1のm_int1に100を入れる*/  /*以下間違え*/  class1 C2_1;/*別のclass1のオブジェクトなのでこれに入れてもダメっぽい*/  C2_1.m_int1 = 100; } void main(){  class1 C1;  C1.m_int1 = 10;  C1.m_class2.func(); } C1.m_class2.func()の中から呼び出したC1にアクセスする方法が 分かりません(TT)。実体がまだあるのだからアクセスする方法は あると思うのですが・・・ どなたかよろしくお願いします。

  • C#でクラス継承について

    下記のようなコードは、可能なのでしょうか? // クラス定義 abstract class Base { int a; Public int A { get{ return a; } } } class Sub1 : Base { int b; public int B { set { b = value; } } }; class Sub2 : Base { // 中略 } static class Program { [STAThread] static void Main(string [] args) { Base aaa = new Sub1(); Base bbb = new Sub2(); func(aaa); // ここでCS1502, CS1503 func(bbb); // ここでCS1502, CS1503 } void func(Sub1 _aaa) { // 中略 } void func(Sub2 _bbb) { // 中略 } } コメントに書いたとおり、CS1502(引数が合わない)が出ます。 func((Sub1)aaa); の様にキャストしないと、動作させることは難しいでしょうか? ※ 実際のコードでは、func(aaa), func(bbb)の呼び出し部分をループでまわしたいと考えています。

  • C++テンプレートクラスの内部クラスについて

    テンプレートクラスについていろいろ試していたところ以下のようなコードで struct A {     struct AA { };     operator A::AA() { return A::AA(); } // (1) }; template<typename T> struct B {     struct BB { };     template<typename U>     operator B<U>() { return B<U>(); } // (2)     template<typename U>     operator typename B<U>::BB() { return typename B<U>::BB(); } // (3) }; int main() {     static_cast<A::AA>(A()); // (1) ok     static_cast<B<int> >(B<short>()); // (2) ok     static_cast<B<int>::BB>(B<short>()); // (3) compile error     return 0; } (1)と(2)はできて(3)だけがコンパイルを通りませんでした。 試したコンパイラはVC9とg++(3.3.4)とbcc32(5.5.1)で、VC9では以下のようなエラーをはきました。 「error C2440: 'static_cast' : 'B<T>' から 'B<T>::BB' に変換できません。     with [ T=short ] and [ T=int ] コンストラクタはソース型を持てません、またはコンストラクタのオーバーロードの解決があいまいです。」 (1)と(2)ができれば(3)のようなこともできそうな感じがしたのですが、他に書き方があるのでしょうか。 どなたかご存知の方がいらっしゃいましたらご教示お願いします。

  • ヘッダのインクルード時のエラー

    初歩的な質問で恐縮です。 以下のようなファイルの構成でc++のプログラムを組んでいます。 <header.h> class H { public: virtual void func() = 0; }; <fileA.cpp> #include "header.h" class A : public H { public: void func() {} }; <fileB.cpp> #include "header.h" class B : public H { public: void func() {} }; <main.cpp> #include "fileA.cpp" #include "fileB.cpp" int main() { A a; B b; a.func(); b.func(); return 0; } これをビルドしようとすると、「クラス"H"を再定義しようとしています」とエラーが出てコンパイルができません。理屈は分かるのですが、これの対処方法が分かりません。この場合、header.hはJAVAにおけるInterfaceのような役割としてそれを使うfileA.cpp、fileB.cppの両者にインクルードしておきたいのです。これはどのようにして対処すべきなのでしょうか?

  • 可変長引数をもつオーバライド関数について

    オーバライド関数について質問があります。 以下のようなクラスAとBがあります。 クラスAは基本クラスです。 クラスBはクラスAから導出しました。 ------------------------------------ CLASS A { public: virtual void func(char* p, ...); } ------------------------------------ CLASS B : public A { public: void func(char* p, ...); } ------------------------------------ メンバ関数の func() はオーバライド関数で、可変長の引数を持っています。 今、クラスBの func() の中で、クラスAの func() をコールするようにコーディングしました。 ----------------------------------- void B::func(char* p, ...) { : : A::func( ???? ) : : } ----------------------------------- ところが、クラスBの func()が受け取った引数を、そのままクラスAの func() に渡したいのですが、どうしたらいいのか分かりません。これって無理でしょうか? 教えて下さい。

  • 用語の正式名称は?(C++)

    C++のクラスや構造体で、 class TEST { private: int a; //A int func1(); //B protected: int b; //C int func2(); //D public: int c; //E int func3(); //F } struct XXX { int x; //G } というのがあったとします。 //A~//G の正式な読み方はなんでしょうか? たとえば//Bなら、「プライベートメソッド」「プライベートメンバ関数」ですか? ご存知なかた、ご教授おねがいします。 できればその定義が書かれていた出所(URL)もおしえてください。

  • 配列の数を途中で増やすには?

    はじめまして。 この度、以下のようなプログラムを作りました。 が、途中で配列の数を増やすことになってしまいました。 ------------------------------------------------ struct a{ int int_a; long int_b; }; struct b{ a *aa; }; void main(void){ b *bb; bb = new b[3]; bb[0].aa = new a[5]; bb[1].aa = new a[4]; . . . } ------------------------------------------------ 具体的には、'bb'の配列を3から5に増やすようなやり方を探しています。 元の配列より大きい配列をつくり、そこにコピーすればいいと考えたのですが、 'bb'内の'aa'の配列も動的に作成しているため、それも出来ない状況です。 どなたかやり方を知っている方がいましたら、教えていただきたいです。 下手な説明ですいません。

  • java

    次のコード中の括弧内で下に示す11通りの各コードを実行した場合の実行画面を正確に答えよ。 class A{ public void func1(){System.out.println("A1");} public void func2(){System.out.println("A2");} } class B extends A{ public void func1(){System.out.println("B");} } class C{ public int x=0, y=1; } class D extends C{ public int x=2; public void func1(int x){System.out.println(x);} public void func2(int x){System.out.println(this.x);} public void func3(int x){System.out.println(super.x);} public void func4(int x){System.out.println(this.y);} public void func5(int x){System.out.println(super.y);} } class E{ public void func1(int n){ try{ System.out.println("E1"); int[] ary=new int[n]; System.out.println("E2"); }catch(NegativeArraySizeException e){ System.out.println("E3"); }finally{ System.out.println("E4"); } } } (1) A a=new A(); a.func1(); (2) A a=new B(); a.func1(); (3) B b=new B(); b.func1(); (4) B b=new B(); b.func2(); (5) D d=new D(); d.func1(3); (6) D d=new D(); d.func2(3); (7) D d=new D(); d.func3(3); (8) D d=new D(); d.func4(3); (9) D d=new D(); d.func5(3); (10) E e=new E(); e.func1(5); (11) E e=new E(); e.func1(-2); (1) A1 (2)B (3)B (4) A2 (5) 3 (6) 2 (7) 0 (8) 1 (9) 1 (10) E1E2E4(11) E1E3E4 と答えになるんですがなぜこうなるのかわかりません。教えてください

    • ベストアンサー
    • Java
  • C++ クラス概念

    以下の違いがよく理解できていません。 どなたかご教授お願い致します。 (1)クラスのメンバー変数に static を付けた場合と、 メンバーではない変数に static を付けた場合の違い (2)クラスのメンバー関数に static を付けた場合と、 メンバーではない関数に static を付けた場合の違い [プログラム例] class MyClass { public: static int internalCount; static void func(MyClass& a) {/* ... */} }; static int i; static void f(MyClass& a) { /* ... */ }

専門家に質問してみよう