こんにちは。質問させてください。
現在下記のような処理(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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラムを教えてください。...
-
戻り値を返す関数の前に(void)...
-
LNK2019:未解決の外部シンボル ...
-
(void)0 はどんな意味ですか
-
PICのプログラミングについて
-
関数の戻り値にその関数のポイ...
-
int main()、void main()、void...
-
C# Controls.Addで動的に配置し...
-
pictureboxの画像を削除するには?
-
質問が多いです・・・・
-
カノニカルモードの設定について
-
2÷3などの余りについて
-
信頼区間の1.96や1.65ってどこ...
-
std::set<int> で、ある値が何...
-
「Aに対するBの割合」と「Aに対...
-
ウィンドウハンドルがメッセー...
-
プログラムでの数字につく”f”の...
-
ある商品のロス率を5%見込み、...
-
10進数からN進数に変換するプロ...
-
O(n log n)について2
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
C++にてtemplateで受け取った任...
-
戻り値を返す関数の前に(void)...
-
静的でないメンバ関数の呼び出...
-
多重定義が起きている?--lnk20...
-
既定のコンストラクタがありま...
-
C# Controls.Addで動的に配置し...
-
int main()、void main()、void...
-
void*型の配列について
-
(void)0 はどんな意味ですか
-
gcc: incompatible pointer type
-
C# KeyDownイベントでショート...
-
C言語 ① 5秒間 1秒間隔で点滅を...
-
Notepad++の関数リスト表示の変...
-
コールバックって・・・
-
マルチメディアタイマーの使用方法
-
_beginthreadにて発生するコン...
-
C#でラジオボタンを設定に記録...
-
VC++でGetKeyboardStateがうま...
-
typedef unsigned int UINT;が...
おすすめ情報