C言語・C++で発生する Visual Studio コンパイラ エラー C2790 について解説
Microsoft Visual Studio のコンパイラで発生するエラー C2790 は、クラスのメンバー関数以外の場所で __super
キーワードを使用した際に表示されます。
C++ の仕様に基づき、__super
は基底クラスのメンバーにアクセスするため、グローバル関数など不適切な文脈で使用するとエラーとなります。
コード内で正しい位置に配置するよう注意してください。
エラー C2790 の発生原因
Visual Studio のコンパイラで発生するエラー C2790 は、キーワード __super
の使用に関する制限が原因です。
このエラーは、メンバー関数の本体内以外で __super
を使用する場合に発生します。
つまり、クラスの外側や静的関数などで利用しようとするとコンパイラが警告を出します。
正しい文脈で使用されなかった場合に、このエラーが出力されるため、コード内の位置に注意が必要です。
キーワード ‘__super’ の利用制限
__super
は、C++ において親クラスのメンバー関数にアクセスするための Microsoft 独自拡張機能です。
使用できるのは、あくまでメンバー関数の本体内だけであり、関数宣言部分やクラス外のグローバル関数、あるいは静的メンバー関数内では利用できません。
Microsoft のドキュメントでも、__super
はメンバー関数の内部でのみ使用するように示されています。
そのため、誤ってクラスの外側で使用すると、コンパイラは位置が不適切であると判断し、エラー C2790 を発生させます。
メンバー関数外での不適切な使用例
以下のようなコード例では、メンバー関数の外で __super
を使用しているため、C2790 エラーが発生します。
#include <iostream>
// 基底クラス Base を定義
class Base {
public:
void g() {
std::cout << "Base::g() called" << std::endl;
}
};
// 派生クラス Derived を定義
class Derived : public Base {
public:
// 正しい利用はメンバー関数内での呼び出し
void callBase() {
__super::g(); // 正しい使い方です
}
};
// グローバル関数内で __super を呼び出すとエラーが発生する例
void invalidUsage() {
__super::g(); // エラー C2790 が発生します
}
int main() {
Derived d;
d.callBase();
return 0;
}
上記のコードでは、グローバル関数 invalidUsage
内で __super
を使用しているため、コンパイラが正しい文脈でないと判断しエラーを出します。
エラー発生時の状況とメッセージ解説
エラー C2790 は Visual Studio でコンパイル作業中に表示され、主にコード中の __super
の使用場所が間違っていることを示します。
コンパイラは、どの部分が不正な使用であるかをエラーメッセージとして出力し、エラーの原因を明確に伝えます。
Visual Studio におけるエラーメッセージの出力例
Visual Studio で該当のコードをコンパイルすると、以下のようなエラーメッセージが表示されます。
- 「
'__super' : このキーワードはクラス メンバー関数の本体内でのみ使用できます
」
このエラーメッセージは、__super
の使用位置が正しくないことを示しており、該当するコードを修正する必要があることを知らせています。
エラーコード C2790 の具体的意味
エラーコード C2790 は、コンパイラがクラスのメンバー関数以外の場所で __super
を使用しようとしたことにより発生します。
具体的には、以下のような意味があります。
- キーワード
__super
は親クラスのメンバー関数にアクセスするために予約されており、使用可能な場所はメンバー関数の本体内に限定されます。 - クラス外や静的関数内で使用すると、その場所はメンバー関数のコンテキストではないため、コンパイラは正しい文脈で使われていないと判断します。
エラーメッセージに含まれるキーワードの解説
エラーメッセージ内で出力されるキーワード __super
は、親クラスへのアクセスを補助するための特別なキーワードです。
通常、派生クラスから明示的に基底クラスのメンバー関数を呼び出す際に利用されます。
正しい場所であれば、コードの明瞭性と保守性を高める役割を果たしますが、間違った場所で使用すると同様のエラーが発生するため、注意が必要です。
対処方法と回避策の解説
エラー C2790 を避けるためには、__super
を正しい文脈で使用することが重要です。
具体的には、必ずクラスのメンバー関数の本体内で使用するように心掛ける必要があります。
正しい利用方法の提示
正しい利用方法として、派生クラスのメンバー関数内で親クラスの関数を呼び出す方法を採用します。
下記のコード例は、正しい利用方法を示しています。
メンバー関数内での利用例
#include <iostream>
// 基底クラス Base を定義します
class Base {
public:
// 基底クラスの関数 g を定義します
void g() {
std::cout << "Base::g() called" << std::endl;
}
};
// 派生クラス Derived を定義します
class Derived : public Base {
public:
// メンバー関数内で __super を用いて基底クラスの関数を呼び出します
void callBase() {
__super::g(); // ここでの使い方が正しいです
}
};
int main() {
Derived derived;
derived.callBase(); // 出力: Base::g() called
return 0;
}
この例では、派生クラス Derived
内のメンバー関数 callBase
の本体内で __super::g()
を正しく使用しています。
不適切な使用例との比較
不適切な使用例として、クラス外または静的関数内で __super
を使った場合を以下に示します。
#include <iostream>
class Base {
public:
void g() {
std::cout << "Base::g() called" << std::endl;
}
};
class Derived : public Base {
public:
void callBase() {
__super::g(); // この位置は正しいです
}
};
// グローバル関数内での __super の使用は不適切です
void invalidUsage() {
__super::g(); // エラー C2790 が発生します
}
int main() {
Derived d;
d.callBase();
// invalidUsage() の呼び出しは避ける必要があります
return 0;
}
上記のコードでは、グローバル関数 invalidUsage
内における __super
の使用が問題となるため、必ずメンバー関数内で利用するように修正してください。
コンパイル修正の手順
エラー C2790 が発生した場合は、まず __super
の使用箇所を確認します。
以下の手順を参考に修正を行ってください。
- エラーメッセージで示されたファイルと行番号を確認する。
- 該当箇所がメンバー関数の本体内であるかどうかを点検する。
- メンバー関数以外で使用されている場合は、そのコードを該当するメンバー関数内に移動、または別の適切な方法に書き換える。
- 変更後、再度コンパイルしてエラーが解消されたか確認する。
この手順を踏むことで、エラーの原因を特定し、適切な位置で __super
を利用できるようになります。
サンプルコードによる実践的検証
実際のサンプルコードを用いて、エラー C2790 の原因と対策を具体的に検証します。
修正前と修正後のコード例を比較することで、正しい使い方を把握してください。
修正前のコード例の分析
修正前のコード例には、グローバル関数内で __super
を使用している箇所が含まれており、これが原因でエラー C2790 が発生します。
#include <iostream>
class Base {
public:
void g() {
std::cout << "Base::g() called" << std::endl;
}
};
class Derived : public Base {
public:
void validCall() {
__super::g(); // この呼び出しは正しいです
}
};
// 以下のグローバル関数は不適切な使用例です
void invalidCall() {
__super::g(); // エラー C2790 が発生します
}
int main() {
Derived d;
d.validCall();
// invalidCall() の呼び出しは削除または修正が必要です
return 0;
}
このコードでは、クラスのメンバー関数外での __super
の使用、「invalidCall」関数内での箇所が問題となっています。
修正後のコード例のポイント
修正後のコード例では、すべての __super
の呼び出しがメンバー関数の本体内に配置されています。
そのため、エラー C2790 は発生せずに正常にコンパイルされます。
#include <iostream>
class Base {
public:
void g() {
std::cout << "Base::g() called" << std::endl;
}
};
class Derived : public Base {
public:
// 基底クラスの関数呼び出しをメンバー関数内に配置
void callBase() {
__super::g();
}
};
int main() {
Derived derived;
derived.callBase(); // 出力: Base::g() called
return 0;
}
この修正後のコード例では、グローバル関数による不適切な呼び出しが削除され、派生クラスのメンバー関数内で正常に __super
を利用していることがポイントです。
注意点とトラブルシューティング
エラー C2790 の対処にあたっては、いくつかの注意点やトラブルシューティングのポイントがあります。
特に初心者は、コード内のキーワード使用位置に慣れていない場合が多いため、注意が必要です。
初心者が陥りやすい誤用例
初心者がよく陥る誤用例として、以下のようなケースが挙げられます。
- クラス外のグローバル関数内で
__super
を使ってしまう - 静的メンバー関数内で
__super
を利用しようとする - コードのリファクタリング中に、意図せず関数外に
__super
呼び出しが残ってしまう
その結果、Visual Studio でエラー C2790 が発生し、どこで誤りが起こっているか判断が難しくなる場合があります。
これを防ぐために、コードレビューや静的解析ツールの利用を検討すると良いでしょう。
開発環境固有の注意事項
Visual Studio のバージョンや設定によっては、エラーメッセージの詳細が異なる場合があります。
また、プロジェクトの構成や使用している C++ の標準、あるいは Microsoft 独自拡張機能のバージョンの違いにより、同じコードでも挙動が異なるケースがあります。
そのため、特に大規模なプロジェクト管理や複数の開発環境が混在する場合は、以下の点に注意してください。
- 各環境でのコンパイラ設定を統一する
- プロジェクト間で使用する C++ の標準を明確にする
- Microsoft の公式ドキュメントで最新情報を確認する
これらの注意点を意識することで、エラー C2790 以外の予期しない問題も回避しやすくなります。
まとめ
この記事では、Visual Studio におけるエラー C2790 の原因と対策について説明しています。
主な原因は、Microsoft 独自のキーワード __super
がメンバー関数以外で使用された場合に発生する点です。
正しい使い方は、派生クラス内のメンバー関数で親クラスの機能を呼び出すことです。
また、不適切な使用例や具体的な修正手順、サンプルコードによる検証方法、初心者向けの注意点についても詳しく解説しており、開発環境でのトラブルシューティングに役立ちます。