EDIT、明確化自分自身を失った:私はオーバーロードされた演算子を使って自分のクラスのEventListenerを使用してのeventHandlersを設定できるようにしたい * >>
と私はこの問題は、オーバーロード>>=
オペレータがパラメータなeventHandlerとは一致しません、私はそれを正しく宣言する方法がわからないということです*>>オーバーロードされた演算子を使用して新規なeventHandlerを作成しようとすると、必要な構文を理解しようと
ための構文を把握することはできません!私はそれを一致させる場合は
OR
、まともな便利なのEventHandlerオブジェクトにジェネリックTタイプを変換するために必要な情報がを消えた!!宣言ではジェネリック型Tを、ジェネリック型では第二のジェネリック型をパラメータとして混合構文が必要です。
eventHandlerクラスの親を使用すると、efunctorもパラメータ化されていないので無駄です。
例:
リンク>>新なeventHandler(&のApp :: testFunction、アプリ);/*where app is an istance of App class and testFunction is a method of App. */
私はeventHandler
と呼ばれるクラスを持っています。このフォームは、eventHandler<class T>
です。今、私は私がこのようにそれを使用できるようにするためにいくつかのクラスの>>
オペレータをオーバーロードしたい:アプリケーションが別のクラスで、testFunctionは、明らかに、そのクラスのメソッドである
link >> new eventHandler(&App::testFunction, App);
。 aboseと書かれた行は、リンクのクラスの>>=
オペレータ(便利にはLink
と呼ばれます)への呼び出しを効果的に持つべきです。
私はそれをより明確にするために私のコードの一部を掲載します:
class Link
{
public:
eventListener* EventListener;
Link()
{
this->EventListener = new eventListener();
}
// PROBLEM
// I am lost here, tried different syntaxes but with no success
//template<template<class G> class T, class F>
template <class T>
Link operator>>=(T& ev)
{
cout << "something";
// Here there is no way to declare the proper eventHandler
eventHandler<?>* event = (eventHandler<?>)ev;
// I need something like T<F>
event->eventName = 'onTest';
this->eventListener->add(event);
return *this;
}
};
template<class T, class F>
T operator>>(T& lhs, F& rhs)
{
return T(lhs)>>=rhs;
}
class App
{
public:
void testFunction(e evt)
{
cout << "it works!" << "\n";
}
};
int main()
{
App* app = new App;
Link* link = new link;
Link link1;
eventHandler<App>* ev = new eventHandler<App>(app, &App::testFunction);
link1 >> ev;
// this line should echo "it works!"
link1.EventListener->triggerEvent("onTest");
// PART 2
// HOW CAN I USE?
// link >> ev;
// when link is a Link*
return 0;
}
私の質問は私の機能のようなものを可能にするように自動的にリンクからメソッドoperator>>=
を宣言する方法についてです。
説明: - 右手オペランドとして実際のeventHandlerを持つLinkクラスの>>
演算子を使用して、新しいEventHandlerをEventListenerクラスに追加できます。
EDIT 1:
そして、私は2番目の質問を持っている: 私はリンク・クラスへのポインタで呼び出されるように>>
オーバーロードされた関数を宣言するためにどのように...私は何ができるかを意味し、私がしたい場合はlink1
の代わりにlink
と>>
を使用してください。
Answer Part2:私の推測では、演算子のオーバーロードを使用するためにポインタを間接参照する必要があります。
ANOTHER EDIT
これは、それが少し良く説明するかもしれないコードのバージョンです。私の問題は、コンパイラが失敗した箇所です。>>=
オペレータをLinkクラス内でマッチングさせると、そこから問題が解決するかどうか、問題の解決方法が見つからず、イベントシグネチャを保持できません。
そして今、私はより良いコードが自身のために話すましょう:
#include <iostream>
#include <stdio.h>
#include "events/events.h"
using namespace std;
class Link
{
public:
eventListener* EventListener;
public:
Link()
{
this->EventListener = new eventListener();
}
template<class T>
Link operator>>=(const T& ev)
{
ev->eventName = "onReceive";
this->EventListener->add(ev);
return *this;
}
};
template<class T, class F>
T operator>>(T& lhs, const F& rhs)
{
return T(lhs)<<=rhs;
}
class App
{
public:
void testReceive(e evt)
{
cout << "it works" << "\n" << evt.value;
}
};
class demo
{
public:
Link* parent;
void testit(char* msg)
{
parent->EventListener->triggerEvent("onReceive", this, msg);
}
};
int main()
{
App* app = new App;
Link link;
eventHandler<App>* ev = new eventHandler<App>(app, &App::testReceive);
link >> ev;
demo d;
d.parent = &link;
// should output "it works!"
d.testit("here");
return 0;
}
私も自分のイベントの定義を掲載します:
#ifndef EVENTS_H
#define EVENTS_H
#include <stdio.h>
#include <string.h>
#include "clist.h"
#include <string>
enum scope {global = 0, scoped};
struct e
{
void* target;
void* value;
};
class efunctor //abstract
{
public:
std::string eventname;
virtual void operator()(e evt)
{ }
virtual void Call(e evt)
{ }
};
template <class T>
class eventHandler : public efunctor
{
private:
T* scope;
void (T::*eventMethod)(e);
public:
std::string name;
std::string eventname;
eventHandler(std::string eventnam, T* objscope, void(T::*func)(e))
{
this->scope = objscope;
this->eventMethod = func;
this->eventname = eventnam;
}
eventHandler(T* objscope, void(T::*func)(e))
{
this->scope = objscope;
this->eventMethod = func;
}
eventHandler(void(T::*func)(e))
{
this->eventMethod = func;
}
void operator()(e evt)
{
(scope->*eventMethod)(evt);
}
void Call(e evt)
{
(scope->*eventMethod)(evt);
}
};
class eventListener
{
private:
clist< clist<efunctor* > > methods;
public:
template <class T>
void add(T other)
{
other->name = ToString(this->methods[other->eventname].length());
methods[other->eventname][methods[other->eventname].length()] = other;
}
template <class T>
void remove(T other)
{
methods[other->eventname]->remove(other->name);
}
template <class F>
void triggerEvent(std::string name, void* target, F result)
{
e evt;
evt.target = target;
evt.value = (char*)result;
for(methods[name].iterateStart();
!methods[name].eoi();
methods[name].next())
{
(*(methods[name].getCurrentIteration()))(evt);
}
}
};
#endif
あり 'new'とない非常にRAIIの非常に多くがあるか'削除'あなたのコードで。 –
さて、私はそれが最初に働いていることを見て、それから世話したいと思います。 – khael
このようなコードを書き留めたり(共有しないでください)、それは悪い先例を設定します。さらに、私は本当にあなたの問題が何であるかを把握するのに苦労しているので、明確にしたいかもしれません。 – Grizzly