次の方法で共有


クラス デザイナーで C++ コードを操作する

クラス デザイナー には、プロジェクト内のコード要素を視覚的に表現する クラス ダイアグラム と呼ばれるビジュアル デザイン サーフェイスが表示されます。 クラス ダイアグラムを使用して、プロジェクト内のクラスやその他の型を設計および視覚化できます。

クラス デザイナー では、次の C++ コード要素がサポートされています。

  • クラス (複数の継承リレーションシップを持つことがある点を除き、マネージド クラスの図形に似ています)

  • 匿名クラス (匿名型のクラス ビューで生成された名前が表示されます)

  • Template クラス

  • 構造体

  • Enum

  • マクロ (マクロの後処理されたビューを表示します)

  • Typedef

これは、モデリング プロジェクトで作成できる UML クラス図と同じではありません。 詳細については、「 UML クラス図: リファレンス」を参照してください

クラス デザイナーの C++ クラス

クラス デザイナー は、C++ クラスをサポートし、Visual Basic および C# クラス図形と同じ方法でネイティブ C++ クラスを視覚化します。ただし、C++ クラスは複数の継承リレーションシップを持つことができます。 クラス図形を展開して、クラス内のフィールドやメソッドをさらに表示したり、折りたたんでスペースを節約したりできます。

クラス デザイナー は共用体をサポートしていません (割り当てられたメモリが共用体の最大データ メンバーに必要な量だけである特殊なクラス型)。

単純な継承

複数のクラスを 1 つのクラス ダイアグラムにドラッグし、クラスにクラス継承リレーションシップがある場合は、矢印によってそれらのクラスが接続されます。 矢印は基底クラスの方向を指します。 たとえば、次のクラスがクラス ダイアグラムに表示されている場合、矢印は B から A を指して接続します。

class A {};
class B : A {};

クラス B のみをクラス ダイアグラムにドラッグし、B のクラス図形を右クリックして、[ 基底クラスの表示] をクリックすることもできます。 これにより、基底クラス A が表示されます。

多重継承

クラス デザイナー では、複数クラスの継承リレーションシップの視覚化がサポートされています。 複数の継承 は、派生クラスに複数の基底クラスの属性がある場合に使用されます。 多重継承の例を次に示します。

class Bird {};
class Swimmer {};
class Penguin : public Bird, public Swimmer {};

複数のクラスをクラス ダイアグラムにドラッグし、クラスに複数クラスの継承リレーションシップがある場合は、矢印によってそれらのクラスが接続されます。 矢印は基底クラスの方向を指します。

クラス図形を右クリックし、[基底クラスの 表示 ] をクリックすると、選択したクラスの基底クラスが表示されます。

派生 クラスの表示 コマンドは、C++ コードではサポートされていません。 派生クラスを表示するには、 クラス ビューに移動し、型ノードを展開し、[ 派生型 ] サブフォルダーを展開して、それらの型をクラス ダイアグラムにドラッグします。

複数クラスの継承の詳細については、「複数の 継承 」と「 複数の基底クラス」を参照してください。

抽象クラス

クラス デザイナー では、抽象クラス ("抽象基底クラス" とも呼ばれます) がサポートされます。 これらはインスタンス化しないクラスですが、そこから他のクラスを派生させることができます。 このドキュメントの前の「多重継承」の例を使用して、次のように Bird クラスを個々のオブジェクトとしてインスタンス化できます。

int main()
{
   Bird sparrow;
   Bird crow;
   Bird eagle;
}

ただし、 Swimmer クラスを個々のオブジェクトとしてインスタンス化しない場合があります。 PenguinWhaleFishなど、他の種類の動物クラスのみを派生させる場合があります。 その場合は、 Swimmer クラスを抽象基底クラスとして宣言します。

クラスを抽象として宣言するには、 abstract キーワードを使用できます。 抽象としてマークされたメンバーまたは抽象クラスに含まれるメンバーは仮想であり、抽象クラスから派生するクラスによって実装される必要があります。

class Swimmer abstract
{
   virtual void swim();
   void dive();
};

少なくとも 1 つの純粋仮想関数を含めることで、クラスを抽象として宣言することもできます。

class Swimmer
{
   virtual void swim() = 0;
   void dive();
};

クラス ダイアグラムでこれらの宣言を表示すると、クラス名 Swimmer とその純粋な仮想関数 swim は、抽象クラスの形式で斜体で表示され、 抽象クラスの表記と共に表示されます。 抽象クラス型の図形は、通常のクラスの図形と同じであることに注意してください。ただし、境界線が点線である点が異なります。

抽象基底クラスから派生したクラスは、基底クラス内の各純粋仮想関数をオーバーライドする必要があります。または、派生クラスをインスタンス化できません。 そのため、たとえば、Fish クラスからSwimmer クラスを派生させる場合、Fishswim メソッドをオーバーライドする必要があります。

class Fish : public Swimmer
{
   void swim(int speed);
};

int main()
{
   Fish guppy;
}

クラス ダイアグラムにこのコードを表示すると、 クラス デザイナーFish から Swimmerへの継承線を描画します。

匿名クラス

クラス デザイナー では、匿名クラスがサポートされています。 匿名クラス型 は、識別子なしで宣言されたクラスです。 コンストラクターまたはデストラクターを持つことはできません。関数に引数として渡すことはできず、関数からの戻り値として返すことはできません。 次の例のように、匿名クラスを使用してクラス名を typedef 名に置き換えることができます。

typedef struct
{
    unsigned x;
    unsigned y;
} POINT;

構造体は匿名にすることもできます。 クラス デザイナー では、匿名クラスと構造体が、それぞれの型を表示するのと同じように表示されます。 匿名のクラスと構造体を宣言して表示することはできますが、 クラス デザイナー では、指定したタグ名は使用されません。 クラス ビューで生成される名前を使用します。 クラスまたは構造体は、クラス ビューと クラス デザイナー、__unnamedという要素として表示されます。

匿名クラスの詳細については、「 匿名クラス型」を参照してください

テンプレート クラス

クラス デザイナー では、テンプレート クラスの視覚化がサポートされています。 入れ子構造の宣言がサポートされています。 次の表は、いくつかの一般的な宣言を示しています。

Code 要素 クラス デザイナー ビュー
template <class T>

class A {};
A<T>

Template クラス
template <class T, class U>

class A {};
A<T, U>

Template クラス
template <class T, int i>

class A {};
A<T, i>

テンプレートのクラス
template <class T, template <class K> class U>

class A {};
A<T, U>

テンプレート クラス

次の表に、部分的特殊化の例をいくつか示します。

Code 要素 クラス デザイナー ビュー
template<class T, class U>

class A {};
A<T, U>

Template クラス
template<class T>

class A<T, T> {};
A<T, T>

テンプレート クラス
template <class T>

class A<T, int> {};
A<T, int>

Template クラス
template <class T1, class T2>

class A<T1*, T2*> {};
A<T1*, T2*>

テンプレート クラス

次の表は、部分的特殊化での継承の例をいくつか示しています。

Code 要素 クラス デザイナー ビュー
template <class T, class U>

class A {};

template <class TC>

class A<T, int> {};

class B : A<int, float>

{};

class C : A<int, int>

{};
A<T, U>

テンプレートクラス

B

クラス

(クラス A を指す)

C

クラス

(クラス A を指す)

次の表に、部分的特殊化テンプレート関数の例をいくつか示します。

Code 要素 クラス デザイナー ビュー
class A

{

template <class T, class U>

void func(T a, U b);

template <class T>

void func(T a, int b);

};
A

func<T、U> (+ 1 オーバーロード)
template <class T1>

class A {

template <class T2>

class B {};

};

template<> template<>

class A<type>::B<type> {};
A<T1>

テンプレートクラス

B<T2>

テンプレートクラス

(B は、ネスト型のクラス A に含まれています)
template <class T>

class C {};

class A : C<int> {};
A

クラス

-> C<int>

C<T>

Template クラス

次の表に、テンプレートの継承の例をいくつか示します。

Code 要素 クラス デザイナー ビュー
template <class T>

class C {};

template<>

class C<int> {

class B {};

}

class A : C<int>::B {};
A

クラス

->B

C<int>

クラス

(B は、ネスト型のクラス C に含まれています)

C<T>

Template クラス

次の表に、正規の特殊なクラス接続の例をいくつか示します。

Code 要素 クラスデザイナービュー
template <class T>

class C {};

template<>

class C<int> {};

class A : C<int> {};

class D : C<float> {};
A

クラス

->C<int>

C<int>

クラス

C<T>

Template クラス

D

クラス

->C<float>
class B {

template <class T>

T min (const T &a, const T &b);

};
B

min <T>

クラス デザイナーの C++ 列挙型

クラス デザイナー では、C++ の enum とスコープ指定された enum class 型がサポートされます。 次に例を示します。

enum CardSuit {
   Diamonds = 1,
   Hearts = 2,
   Clubs = 3,
   Spades = 4
};

// or...
enum class CardSuit {
   Diamonds = 1,
   Hearts = 2,
   Clubs = 3,
   Spades = 4
};

クラス図の C++ 列挙図形は、構造図形と同様に動作しますが、ラベルが Enum クラスまたは Enum クラスを読み取り、青色ではなくピンク色で、左余白と上余白に色付きの罫線が付いている点が異なります。 列挙図形と構造体図形の両方に四角があります。

enum型の使用の詳細については、「列挙型」を参照してください。

クラス デザイナーの C++ 型定義

Typedef ステートメントでは、名前とその基になる型の間に 1 つ以上の間接参照レイヤーが作成されます。 クラス デザイナー では、次のようにキーワード typedefで宣言される C++ typedef 型がサポートされています。

typedef class coord
{
   void P(x,y);
   unsigned x;
   unsigned y;
} COORD;

その後、この型を使用してインスタンスを宣言できます。

COORD OriginPoint;

クラス図形と構造体図形

クラス デザイナーでは、C++ typedef は typedef で指定された型の図形を持ちます。 ソースで typedef class宣言されている場合、図形の角は丸く、 ラベルは Class になりますtypedef structの場合、図形には四角形の角とラベル Struct があります

クラスと構造体には、入れ子になった typedef をその中で宣言できます。 クラス デザイナーでは、クラス図形や構造体図形として、入れ子になった typedef 宣言を表示できます。

Typedef 図形は、右クリック メニュー (コンテキスト メニュー) の [ 関連付けとして表示 ] コマンドと [ コレクションの関連付けとして表示 ] コマンドをサポートします。

クラス typedef の例

class B {};
typedef B MyB;

クラス デザイナーの C++ クラス typedef

構造体 typedef の例

typedef struct mystructtag
{
    int   i;
    double f;
} mystruct;

クラス デザイナーの C++ 構造体 typedef

名前のない typedef

typedef は名前なしで宣言できますが、 クラス デザイナー では指定したタグ名は使用されません。 クラス デザイナー では、 クラス ビュー によって生成される名前が使用されます。 たとえば、次の宣言は有効ですが、 クラス ビュークラス デザイナー では 、__unnamedという名前のオブジェクトとして表示されます。

typedef class coord
{
   void P(x,y);
   unsigned x;
   unsigned y;
};

クラス デザイナー では、ソース型が関数ポインターである typedef は表示されません。

C++ コード要素の制限事項について説明します

  • C++ プロジェクトが読み込まれると、 クラス デザイナー は読み取り専用の方法で機能します。 クラス ダイアグラムは変更できますが、クラス ダイアグラムからソース コードに変更を保存することはできません。

  • クラス デザイナー では、ネイティブ C++ セマンティクスのみがサポートされます。 マネージド コードにコンパイルされた C++ プロジェクトの場合、 クラス デザイナー はネイティブ型のコード要素のみを視覚化します。 そのため、クラス ダイアグラムをプロジェクトに追加できますが、 クラス デザイナー では、 IsManaged プロパティが true に設定されている要素 (つまり、値の型と参照型) を視覚化することはできません。

  • C++ プロジェクトの場合、 クラス デザイナー は型の定義のみを読み取ります。 たとえば、ヘッダー (.h) ファイルで型を定義し、そのメンバーを実装 (.cpp) ファイルで定義するとします。 実装 (.cpp) ファイルで "クラス ダイアグラムの表示" を呼び出した場合、 クラス デザイナー には何も表示されません。 別の例として、 #include ステートメントを使用して他のファイルを含めるが、実際のクラス定義が含まれていない.cpp ファイルに対して "クラス ダイアグラムの表示" を呼び出すと、 クラス デザイナー は再び何も表示しません。

  • COM インターフェイスとタイプ ライブラリを定義する IDL (.idl) ファイルは、ネイティブ C++ コードにコンパイルされない限り、図には表示されません。

  • クラス デザイナー では、グローバル関数と変数はサポートされていません。

  • クラス デザイナー では、共用体はサポートされていません。 これは、割り当てられたメモリが共用体の最大データ メンバーに必要な量だけである特殊なクラスです。

  • クラス デザイナー には、 intcharなどの基本的なデータ型は表示されません。

  • プロジェクトにこれらの型への正しい参照がない場合、現在のプロジェクトの外部で定義されている型はクラス デザイナーに表示されません。

  • クラス デザイナー では入れ子になった型を表示できますが、入れ子になった型と他の型の間のリレーションシップは表示できません。

  • クラス デザイナー では、void または void 型から派生した型を表示できません。

型解決と表示に関する問題のトラブルシューティング

ソース ファイルの場所

クラス デザイナー は、ソース ファイルの場所を追跡しません。 そのため、プロジェクト構造を変更したり、プロジェクト内のソース ファイルを移動したりすると、 クラス デザイナー で型 (特に typedef、基底クラス、または関連付け型のソースの種類) が失われる可能性があります。 クラス デザイナーでこの型を表示できないなどのエラーが表示される場合があります。 その場合は、変更または再配置されたソース コードをもう一度クラス ダイアグラムにドラッグして再表示します。

更新とパフォーマンスの問題

C++ プロジェクトの場合、ソース ファイルの変更がクラス図に表示されるまでに 30 ~ 60 秒かかる場合があります。 この遅延により クラス デザイナー選択内容に型が見つかりませんでした というエラーをスローする可能性があります。 このようなエラーが発生した場合は、エラー メッセージで [キャンセル ] をクリックし、コード要素が クラス ビューに表示されるまで待ちます。 これを行うと、 クラス デザイナー で型を表示できるようになります。

コードで行った変更でクラス ダイアグラムが更新されない場合は、ダイアグラムを閉じて再度開く必要がある場合があります。

型の解決に関する問題

クラス デザイナー では、次の理由により型を解決できない場合があります。

  • この型は、クラス ダイアグラムを含むプロジェクトから参照されていないプロジェクトまたはアセンブリ内にあります。 このエラーを修正するには、型を含むプロジェクトまたはアセンブリへの参照を追加します。 詳細については、「 プロジェクト内の参照の管理」を参照してください。

  • 型が正しいスコープ内にないため、 クラス デザイナー で見つけることができません。 コードに usingimports、または #include ステートメントがないことを確認します。 また、最初に配置された名前空間から型 (または関連する型) を移動していないことを確認します。

  • 型が存在しない (またはコメント アウトされています)。 このエラーを修正するには、型をコメント アウトまたは削除していないことを確認します。

  • 型は、#import ディレクティブによって参照されるライブラリにあります。 考えられる回避策は、生成されたコード (.tlh ファイル) を #include ディレクティブにヘッダー ファイルに手動で追加することです。

  • 入力した型が クラス デザイナー でサポートされていることを確認します。 C++ コード要素の制限事項を参照してください。

型解決の問題で発生する可能性が最も高いエラーは、 クラスダイアグラム '<element>' の 1 つ以上の図形に対して Code が見つからなかった場合です。 このエラー メッセージは、コードがエラーであることを必ずしも示すわけではありません。 これは、クラス デザイナーがコードを表示できなかったことを示します。 次の対策を試してください。

  • 型が存在することを確認します。 ソース コードが意図せずにコメント アウトまたは削除されていないことを確認します。

  • 型を解決してみてください。 型は、クラス ダイアグラムを含むプロジェクトから参照されていないプロジェクトまたはアセンブリ内にある可能性があります。 このエラーを修正するには、型を含むプロジェクトまたはアセンブリへの参照を追加します。 詳細については、「 プロジェクト内の参照の管理」を参照してください。

  • クラス デザイナーが型を見つけられるように、型が正しいスコープにあることを確認します。 コードに usingimports、または #include ステートメントがないことを確認します。 また、最初に配置された名前空間から型 (または関連する型) を移動していないことを確認します。

ヒント

その他のトラブルシューティング情報については、「 クラス デザイナーのエラー」を参照してください。