
こんにちは。質問させてください。
現在下記のような処理(main関数でやっているような処理)を実現させたいのですが、うまくコンパイルできません。
#include <iostream>
class Test
{
public:
void TestFunc()
{
std::cout << "TestFunc" << std::endl;
}
};
class AllowOverLoad
{
public:
Test* operator ->()
{
return new Test;
}
};
int main()
{
void ( Test::*lpTestFunc )() = &Test::TestFunc;
AllowOverLoad overload;
( overload->*lpTestFunc )();
}
主なエラーは
error C2296: '->*' : 無効です。左オペランドには型 'AllowOverLoad' が指定されています。
です。
おそらくこの問題を解決するにはAllowOverLoadに->*演算子をオーバーロードしなくてはいけないと思うのですが、->*演算子のオーバーロード方法がいまいちよくわかりません。
いい文献やHPも見つけられなかったので質問させていただきました。
/*
現在、本番のコーディングでは暗黙的なキャストを禁止しているのでAllowOverLoadクラスに暗黙的にTest*型にキャストするような処理はなしの方向で、あくまで->*演算子のオーバーロードということでお願いします。
Microsoft WindowsXP Professional Edition
VisualStudio 2008 AcademicEdition
*/
よろしくお願いします。
No.1ベストアンサー
- 回答日時:
確かに自分も悩んだ. 結局規格を読んで解決したんだけど.
operator->* は 2項演算子で, a->*b は a.operator ->*(b) と解釈されます. 今の例では overload->*lpTestFunc が overload.operator ->*(lpTestFunc) と解釈されるので, クラス AllowOverLoad に
operator ->*(void (Test::*func)())
を定義する必要があります.
また, この演算子の返り値も注意する必要があります. 返した値を直接関数呼び出しとして使うためには
・「普通の」関数 (へのポインタ) を返す
・operator () がオーバロードされたクラスのオブジェクトを返す
のどちらかが必要になります. ところが, static でないメンバ関数への . 等を使った参照は「ただちに関数呼び出しを行う」ことしかできません. 従って, operator ->*(void (Test::*func)()) では「operator () をオーバロードしたオブジェクトを返す」という作業をしなければなりません. 全体として, 例えば
#include <iostream>
class Test {
public:
void testFunc() { std::cout << "TestFunc" << std::endl; }
};
class Funcall {
public:
Funcall(Test *ptr, void (Test::*func)()) : ptr_(ptr), func_(func) { }
void operator ()() const { return (ptr_->*func_)(); }
private:
Test *ptr_;
void (Test::*func_)();
};
class AllowOverload {
public:
Funcall operator ->*(void (Test::*func)()) { return Funcall(new Test, func);
}
};
int main()
{
void (Test::*lpTestFunc)() = &Test::testFunc;
AllowOverload ovl;
(ovl->*lpTestFunc)();
return 0;
}
とすることで所与の目的を果たすことができます.
とはいえ, 本当にオーバロードが必要なんでしょうか?
とても丁寧な回答ありがとうございます。
なるほど・・・何度か読み返してやっと理解することができました。
自分が予想していたよりもはるかに複雑でむずかしかったです。
実は自作のスマートポインターとメンバ関数ポインタを併用しようとしたら、今回の問題に当たりました。
またもう少し、考察してみます。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java final 1 2022/06/10 22:49
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- その他(プログラミング・Web制作) VScodeでpythonプログラムの関数を実行したい 2 2022/07/13 19:24
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- JavaScript [再掲]指定したパスが現URLに含まれていたら特定要素を削除するJavascriptのコードについて 1 2023/05/10 15:09
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C++にてtemplateで受け取った任...
-
既定のコンストラクタがありま...
-
【gcc・cygwin】multiple defin...
-
多重定義が起きている?--lnk20...
-
const_castのつかいどころを教...
-
gcc: incompatible pointer type
-
【VC++6.0】イベントハンドラ関...
-
VC++でGetKeyboardStateがうま...
-
コールバックって・・・
-
unityの教科書のゲームを作って...
-
pic16f88とosl40562-lrとc言語...
-
C言語 プロトタイプ宣言
-
アドレス渡し?
-
typedef unsigned int UINT;が...
-
C言語 int main(void) main()
-
静的でないメンバ関数の呼び出...
-
メッセージマップ(ON_CONTROL_...
-
C++でオーバーロードに関するバ...
-
GDI+の使用方法について
-
_beginthreadにて発生するコン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
静的でないメンバ関数の呼び出...
-
【gcc・cygwin】multiple defin...
-
戻り値を返す関数の前に(void)...
-
多重定義が起きている?--lnk20...
-
C++にてtemplateで受け取った任...
-
const_castのつかいどころを教...
-
既定のコンストラクタがありま...
-
C# Controls.Addで動的に配置し...
-
(void)0 はどんな意味ですか
-
C#でラジオボタンを設定に記録...
-
ウインドウの移動禁止
-
Notepad++の関数リスト表示の変...
-
Delphiの定数とローカル変数の...
-
typedef unsigned int UINT;が...
-
int main()、void main()、void...
-
C言語 extern について
-
void*型の配列について
-
VC++でGetKeyboardStateがうま...
-
_beginthreadにて発生するコン...
-
gcc: incompatible pointer type
おすすめ情報