2016-10-16 4 views
-1

저는 C++을 처음 접했고 아마도 순진한 문제가있었습니다. 나는 다른 smilar 질문이있다, 그러나 나의 것보다는 더 복잡한 문제에 관련된다 (저에게 보인다)다는 것을 알고있다. C++를 사용하여 Arduino 용 펌웨어를 만들려고하고 있으며 오버로드 오류로 인해 스스로 해를 끼쳤습니다.C++ 기초 : 해결되지 않은 오버로드 된 함수 유형

void class1::functionA(void) 
{ 
    object2.functionOfClass2(class1::functionB); 
} 

클래스 1은 다음과 같이 초기화 :이 코드를

는 CPP 파일에 정의

class class1 
{ 
public: 
void functionA(void); 
void functionB(void); 
private: 
} 

그리고 컴파일에

no matching function for call to 'class2::functionOfClass2(<unresolved overloaded function type>)' 

가로 번역 제공 실용 : 012 내 코드에서

나는 예에서 object2Class2의 각각 와이어있는 아두 이노 라이브러리의 Class1의의 멤버 함수 내부의 와이어 라이브러리를 사용하고 있습니다 클래스의 개체 투 와이어입니다.

라이브러리를 클래스 1의 멤버 함수 내에서 호출해야 할 필요가 있습니다. 이 해결책은 클래스가 아니기 때문에 비 멤버 함수의 인스턴스화를 할 수 없으므로 비 멤버 함수 내에 클래스 1의 멤버 함수를 호출 할 수 없다는 것을 배웠던 이전 수업의 결과입니다. 아직 객체로 인스턴스화되었고 컴파일러는이를 수행하는 방법에 대한 단서를 가지고 있지 않습니다.

그러나 전화는 입니다. 개체가 구성원 함수 안에 있으면 가능하다고 생각했습니다. 그러나 더 나은에 대한 생각의 와이어 함수에 Class1의 멤버 함수 포인터를 전달할 때 실제로, 컴파일러는 와이어에 전달할 것을 알 수 없다, 그래서 다음은 잘못된 것입니다 :

void class1::functionA(void) 
{ 
    Wire.onRequest(class1::functionB); //wrong 
} 

여기서 요청시void (*)(void)을 수락합니다.

그래서

void class1::functionA(void) 
{ 
    Wire.onRequest(&class1::functionB); //wrong 
} 

오류와 시도가되었다 :

error: no matching function for call to 'TwoWire::onRequest(void (class1::*)())' candidates are: void TwoWire::onRequest(void (*)())

것들 작동하게하는 방법이 있나요? 내가 이라고 말하면,이니셜 라이저 목록이 올바른 키워드로 올바른 방법으로 전달되고 있습니까?

감사

+0

내 대답을 삭제해야했습니다. 나는 이것이 명백히 행할 수 있다고 생각하지 않는다. 'class1' 인스턴스의'this'를'onRequest'에 전달해야하며, void (*)() (매개 변수가 허용되지 않음)를 받아들이면 그렇게 할 수 없습니다. 잘 설계된 라이브러리는'onRequest'를'onRequest (void (* callback) (void *), void * context)'로 대신 정의 할 것이고'this'를'context'로 전달할 것입니다. –

+0

이 작업을 수행하는 유일한 방법은 전체 응용 프로그램에 하나의 'class1' 인스턴스가있는 경우입니다. 그러면이 인스턴스를 무조건 대체하고'functionB'를 호출 할 수 있습니다. –

답변

1

&class1::functionB 포인터 멤버 함수가 아닌 함수 포인터입니다. 형식은 onRequest 메서드에서 예상 한대로 void (class1::*)(void)이 아니고 void (*)(void)이 아닙니다. 즉,이 pointer-to-member-function을 호출하려면 인스턴스도 있어야합니다 (class1*).

class1이 싱글 톤일 경우 가장 쉽게 해결할 수있는 방법은 아마도 functionB을 정적 멤버 또는 단순히 비 멤버 함수 (모든 클래스 내부가 아님)로 만드는 것입니다.

class1을 싱글 톤으로 가정 할 수없는 경우 라이브러리에는 함수 포인터를 따라 컨텍스트 포인터 (일반적으로 void*)를 전달하는 방법이 있어야하며이 컨텍스트는 콜백 함수의 매개 변수입니다. 다음과 같이 컨텍스트로 this을 전달하고 래퍼 함수에 대한 포인터를 전달해야합니다.

void wrapper_for_class1_functionB(void* context) 
{ 
    static_cast<class1*>(context)->functionB(); 
} 

void class1::functionA(void) 
{ 
    Wire.onRequest(&wrapper_for_class1_functionB, this); 
} 
+0

목표는 그것을 싱글 톤으로 만들지 않으며, 실제로 데이터 구조가 클래스에 정의되어 있습니다. 즉, 클래스에 정의 된 구조체의 데이터 처리가 포함되어 있기 때문에 비 멤버 함수를 사용할 수 없습니다. – thexeno

+0

그런 다음 제안을 시도해 보았는데 매우 흥미로 보입니다. 그러나 이것은 Wire 라이브러리를 수정하여 또 다른 인수가 필요합니다. 사실, 내가 가진 오류는 일치하지 않는 함수입니다. 내가 놓친 게 있니? – thexeno

+0

그리고 어쨌든 "functionB()"의 함수에는 .cpp 외부에서 호출해야하는 다른 멤버 함수가 있으므로 개체가 생성 될 때 주 파일에서 호출됩니다. – thexeno