나는 내가 쓴이 거대한 응용 프로그램에 대한 "DomainEditor"수업 시간에 그것을했다 요구함으로써
class Fields
{
public:
Fields()
{
fields_.push_back(Field("First Name", &Criteria::firstname));
fields_.push_back(Field("Last Name", &Criteria::lastname));
fields_.push_back(Field("Website", &Criteria::website));
}
template < typename TFunction >
void forEach(TFunction function)
{
std::for_each(fields_.begin(), fields_.end(),
function);
}
private:
std::vector<Field> fields_;
};
. 데이터베이스의 모든 유형 (도메인) 테이블은 프로그램 관리자가 편집 할 수 있으며 클라이언트가 다른 유형과 다른 이름으로 일부 유형을 호출 했으므로 편집 할 수있는 대화 상자를 만들었습니다. 글쎄, 나는 15 개 이상의 도메인 유형에 대한 편집기를 만들고 싶지 않았기 때문에 각 클래스를 캐스팅 할 수있는 수퍼 클래스를 작성하고 각 도메인 테이블에 간단한 호출을 할 수있는 포인터를 사용했다. 각각은 모두 동일한 속성, 설명 (이름), ID, 비활성 플래그 및 필수 플래그를 지원합니다. , 매크로 호출의 많은 그런
#define DomainList(Class, Description, First, Next, Item, UpdateItem, DeleteItem, IsItemRequired, MaxLength) { \
CWFLHandler *handler = new CWFLHandler; \
handler->pWFL = new Class;\
handler->LoadFirstType = (LoadFirst)&Class::First;\
handler->LoadNextType = (LoadNext)&Class::Next;\
handler->LoadType = (Load)&Class::Item;\
handler->UpdateType = (Update)&Class::UpdateItem;\
handler->DeleteType = (Delete)&Class::DeleteItem;\
handler->IsRequiredType= (IsRequired)&Class::IsItemRequired; \
handler->MAX_LENGTH = MaxLength;\
PopulateListBox(m_Domain, Description, (long)handler); }\
: 그래서, 코드가 내 전화 설치에 매크로 시작 (여기에 단지 하나의 하나입니다)
DomainList(CConfigWFL, "Application Parameter Types", LoadFirstParameterType, LoadNextParameterType, LoadParameterTypeByTypeId, UpdateParameterType, DeleteParameterType, IsParameterTypeRequired, LEN_APPL_PARAMETER_DESC);
그런 다음 호출 편집 데이터는 모두 공통적이었고 모든 코드를 복제 할 필요가 없었습니다 ...
예를 들어 DropDownList (매크로로 채워짐)에서 선택한 항목으로 목록을 채우려면 코드가 이렇게 :
if((pWFLPtr->pWFL->*pWFLPtr->LoadFirstType)(true))
{
do
{
m_Grid.AddGridRow();
m_Grid.SetCheck(COLUMN_SYSTEM, (pWFLPtr->pWFL->*pWFLPtr->IsRequiredType)(pWFLPtr->pWFL->TypeId));
m_Grid.SetCheck(COLUMN_STATUS, pWFLPtr->pWFL->InactiveIndc == false);
m_Grid.AddTextToGrid(COLUMN_NAME, pWFLPtr->pWFL->TypeDesc);
m_Grid.AddTextToGrid(COLUMN_DEBUG, pWFLPtr->pWFL->TypeId);
m_Grid.AddTextToGrid(COLUMN_ID, pWFLPtr->pWFL->TypeId);
}
while((pWFLPtr->pWFL->*pWFLPtr->LoadNextType)());
물론 이것은 대화 상자의 일부인 클래스에 저장되었습니다. 그리고 간단히 클래스의 새 인스턴스를 만들어 ListBox의 ItemData 멤버에 저장했습니다. 그래서 대화 상자가 닫히면 모든 것을 정리해야했습니다. 그러나이 메시지에서이 코드를 제외했습니다.
typedef bool (CMyWFL::*LoadFirst)(bool);
typedef bool (CMyWFL::*LoadNext)();
typedef bool (CMyWFL::*Load)(long);
typedef bool (CMyWFL::*Update)(long, const char*, bool);
typedef bool (CMyWFL::*Delete)(long);
typedef bool (CMyWFL::*IsRequired)(long);
class CWFLHandler {
public:
CWFLHandler() {};
~CWFLHandler() { if(pWFL) delete pWFL; }
CMyWFL *pWFL;
LoadFirst LoadFirstType;
LoadNext LoadNextType;
Load LoadType;
Update UpdateType;
Delete DeleteType;
IsRequired IsRequiredType;
int MAX_LENGTH;
};
CWFLHandler *pWFLPtr;
이 모든 일이 도메인에 추가 할 아주 약간의 작업으로 응용 프로그램에 새 도메인을 추가 할 수있는 것이 정말 좋은했다 :
이 모든 물건을 저장하는 클래스는 다음과 같이 정의 하였다 편집장 ... 더 좋은 방법이 있었을지 모르겠다. 하지만 이것은 제가가는 방식입니다. IMHO는 매우 창의적이었습니다. :)
을, 예컨대 그것을 사용하려면 그렇게하지 이중에 대한 Serialisers을했다? – dirkgently
@dirkgently 나는 여기서 mem_fun이 더 적절하다고 생각했습니다. 확인 중 ... – JaredPar
@JaredPar : SomeClass가 포인터가 아닌 경우 mem_fun이 작동하지 않습니다 –