문제

내가 가지고 있다고 가정해 보세요:

void Render(void(*Call)())
{
    D3dDevice->BeginScene();
    Call();
    D3dDevice->EndScene();
    D3dDevice->Present(0,0,0,0);
}

렌더링에 사용하려는 함수가 함수이거나 static 회원 기능:

Render(MainMenuRender);
Render(MainMenu::Render);

그러나 대부분의 경우 렌더링 함수는 멤버 변수에 액세스하기를 원하고 클래스 인스턴스를 전역으로 만들지 않기 때문에 클래스 메서드도 사용할 수 있기를 정말로 원합니다.

Render(MainMenu->Render);

그러나 저는 이 작업을 수행하는 방법을 전혀 모르고 여전히 기능과 static 사용할 멤버 함수.

도움이 되었습니까?

해결책

템플릿을 포함하여 이 고양이의 스킨을 만드는 방법에는 여러 가지가 있습니다.내가 가장 좋아하는 것은 부스트 기능 장기적으로 볼 때 가장 유연하다고 생각했기 때문입니다.다음 내용도 읽어보세요. 부스트.바인드 멤버 함수 및 기타 여러 트릭에 바인딩하는 데 사용됩니다.

다음과 같이 보일 것입니다:

#include <boost/bind.hpp>
#include <boost/function.hpp>

void Render(boost::function0<void> Call)
{
    // as before...
}

Render(boost::bind(&MainMenu::Render, myMainMenuInstance));

다른 팁

래퍼 기능을 만들 수 있습니다 void Wrap(T *t) 그건 그냥 전화 t->Call() 그리고 가지고 Render 그러한 기능을 객체와 함께 취하십시오.그건:

void Wrap(T *t)
{
  t->Call();
}

void Render(void (*f)(T *), T *t)
{
  ...
  f(t);
  ...
}

나는 인스턴스에 대한 포인터를 멤버로 받아들이는 전역 함수 "Call"을 정의하여 한 번 그렇게 했습니다.

void CallRender(myclass *Instance)
{
  Instance->Render();
}

따라서 렌더링은 다음과 같습니다.

void Render(void (*Call)(myclass*), myclass* Instance)
{
  ...
  Call(Instance);
  ...
}

렌더링 호출은 다음과 같습니다.

Render(CallRender, &MainMenu);

나는 그것이 추악하다는 것을 알고 있지만 나에게는 도움이 되었습니다(나는 pthread를 사용하고 있었습니다)

개체에 대한 참조도 없으면 포인터에서 멤버 함수를 호출할 수 없습니다.예를 들어:

((object).*(ptrToMember))

따라서 렌더링 방법의 서명을 변경하지 않으면 이를 달성할 수 없습니다. 이것 기사에서는 이것이 일반적으로 나쁜 생각인 이유를 설명합니다.

더 좋은 방법은 렌더링 메소드가 있는 클래스가 구현할 수 있고 기본 Render 메소드의 매개변수 유형이 되도록 하는 "렌더러" 인터페이스를 정의하는 것입니다.그런 다음 참조로 정적 메서드 호출을 지원하는 "StaticCaller" 구현을 작성할 수 있습니다.

예를 들어 (내 C++은 정말 녹슬었습니다. 이것도 컴파일하지 않았습니다).



void Render(IRenderer *Renderer)
{
    D3dDevice->BeginScene();
    Renderer->Render();
    D3dDevice->EndScene();
    D3dDevice->Present(0,0,0,0);
}

// The "interface"
public class IRenderer 
{
public:
    virtual void Render();
};

public class StaticCaller: public IRenderer
{
    void (*Call)();
public:

    StaticCaller((*Call)())
    {
        this->Call = Call;
    }

    void Render()
    {
        Call();
    }
};

이 모든 것은 꽤 상용구이지만 가독성을 높여야 합니다.

다음을 사용하여 클래스 T의 멤버 함수에 대한 함수 포인터를 선언할 수 있습니다.

typedef void (T::*FUNCTIONPOINTERTYPE)(args..)
FUNCTIONPOINTERTYPE function;

그리고 다음과 같이 호출합니다.

T* t;
FUNCTIONPOINTERTYPE function;
(t->*function)(args..);

가변 인수, 유형, 반환 값 등을 사용하여 이를 유용한 커링 시스템으로 추정하는 것은 단조롭고 짜증스럽습니다.앞서 언급한 부스트 라이브러리에 대해 좋은 소식을 들었으므로 과감한 조치를 취하기 전에 해당 라이브러리를 살펴보는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top