2014-04-07 2 views
1

자식 클래스 개체가 부모 클래스 개체의 메서드를 제어 할 수 있도록 부모 클래스 개체를 자식 클래스 개체로 전달하려고합니다.C++ 클래스가 참조로 전달 될 수 있습니까?

그러나 이로 인해 헤더와 관련된 문제가 발생합니다. 클래스 중 하나를 선언하려고했으나 먼저 선언 된 클래스가 먼저 선언 된 클래스에서 읽는 데 문제가있는 것으로 보입니다.

모두 오류

는 DM의 안녕 세계 메소드를 호출하려고 생성자 '장치를 참조하십시오, 그들은 다음과 같습니다

Use of undefined type 'DeviceManager' 
Left of '->HelloWorld' must point to class/struct/union/generic type 

...

//main.cpp 
#include "parent.h" 

void main() 
{ 
    cout << "Created DeviceManager\n"; 
    DeviceManager* deviceManager = 0; 
    deviceManager = new DeviceManager; 

    cout << "Giving DeviceManager a device\n"; 
    deviceManager->p = new Device(deviceManager); 

    cout << "Giving Device a reference to DevicenManager\n"; 
    deviceManager->Share(); 
} 

...

class DeviceManager; 
class Device 
{ 
public: 
    Device(DeviceManager* manager) 
    { 
       dm = 0; 
     this->dm = manager; 
     this->dm->HelloWorld(); 
    } 

    DeviceManager* dm; 
}; 

//device manager 
class DeviceManager 
{ 
public: 
    DeviceManager() 
    { 
     p = 0; 
    } 
    void HelloWorld() 
    { 
     //if this calls we know the child has control over the parent. 
     cout << "Hello World"; 
    } 

    Device* p; 
}; 
+1

무엇을 참조하여 스스로를 전달합니까? 문제를 보여주는 몇 가지 코드를 공유 할 수 있습니까? 당신의 질문은 지금까지는 그것이 참조의 존재 여부에 의문을 제기하는 것처럼 느껴지므로 명확하지 않습니다. – lpapp

+5

문제를 일으킨 코드를 알려주십시오. 객체가 자신을 참조로 전달하는 것은 완전히 허용 가능합니다. – ApproachingDarknessFish

+0

은 일부 코드를 제공하므로 현재 상황이 이해되기 쉽습니다. – Anthony

답변

4

예.

당신이 클래스 전달-선언 할 수 있습니다, 클래스 멤버와 함수 선언과 순환 종속성을 해결하기 위해 :

class A; 

class B { 
     A *a; 
}; 

class A { 
     B *b; 
}; 

가 다른 클래스의 멤버에 액세스 클래스 멤버 함수를 정의하기를, 당신은 후 기능 를 정의해야합니다 다른 클래스가 정의되어 있습니다 :

class B; 

class A { 
public: 
     void f(B &arg); 
}; 

class B { 
public: 
     void g(A &arg); 
}; 

void A::f(B &arg) { 
     arg.g(*this); 
} 

void B::g(A &arg) { 
     arg.f(*this); 
} 

일반적으로하는 C++ 프로젝트, 당신도이 문제가 발생하지 않을 : 당신은 함수 정의, 즉 IMPL을 둘 것 클래스 정의를 헤더 파일에 넣으면서 .cpp 개의 파일에 저장됩니다. 필요한 경우 클래스 전달 선언은 헤더 전달을 필요로하는 모든 헤더에 포함 된 자체 헤더 파일에 넣을 수 있습니다.

여러 파일에 위의 코드를 분할 할 방법에 대한 전체 예 :

a.cpp

#include "a.h" 

#include "b.h" 

void A::f(B &arg) { 
    arg.g(*this); 
} 

b.cpp

#include "b.h" 

#include "a.h" 

void B::g(A &arg) { 
    arg.f(*this); 
} 

BH

#ifndef _B_H_ 
#define _B_H_ 

#include "forward_declarations.h" 

class B { 
public: 
    void g(A &arg); 
}; 

#endif //_B_H_ 
엄지 손가락의 일반적인 규칙으로

forward_declarations.h

#ifndef _FORWARD_DECLARATIONS_H_ 
#define _FORWARD_DECLARATIONS_H_ 

class A; 
class B; 

#endif //_FORWARD_DECLARATIONS_H_ 

, 당신은 클래스를 전달-선언해야하는 경우, 당신이 뭔가를 misdesigned 수도

#ifndef _A_H_ 
#define _A_H_ 

#include "forward_declarations.h" 

class A { 
public: 
    void f(B &arg); 
}; 

#endif //_A_H_ 

더 나은 방법이 있는지 생각해야합니다 (그러나 클래스 전달 선언이 필요한 완벽하게 유효한 사용 사례도 있습니다).

#ifndef, #define#endif 전처리 라인을 이해하지 않는 경우 :이 가드 헤더, 그리고 와 다른 곳에서 포함 된 모든 파일을 사용해야합니다, 예외가 당신이 알고 정확하게 무엇 ' 다시하고있어. 나를 믿어. 너는 하나를 찬미 할 것이다.

+0

OP가 요청하려고하는 것을 이해 했습니까? 추측보다는 설명을 요구하는 것이 좋습니다 ... 예를 들어, 귀하의 예에서 이야기 한 순환 의존성을 이해할 수 없습니다. 코드에는 원형이 전혀 없습니다. – lpapp

+0

OP가 가장 많이 언급 한 것은 '포함 경로가 무한 루프를 생성합니다'라고 언급했을 때 다른 클래스 선언이 필요한 두 클래스 정의가 원인 인 순환 헤더 종속성이며 클래스를 앞으로 선언하여 해결할 수 있습니다 . –

+0

OP가 묻기를 시도한 것이 무엇인지 알 수 없습니다. 나는 그 명료화를 기다릴 것이다. – lpapp

1

문제는이 같은 순환 의존성 인 경우 :

// DeviceManager.h 
#include "device.h" 
class DeviceManager 
{ 
    DeviceManager(Device& device) {} 
}; 

// Device.h 
#include "DeviceManager.h" 
class Device 
{ 
    Device(DeviceManager& manager) {} 
}; 

당신은 문제가 앞으로 클래스 하나를 선언하고, 포인터로 객체를 전달 될 해결할 수 있습니다.

// Device.h 
//#include "DeviceManager.h" 
class DeviceManager; 
class Device 
{ 
    Device(DeviceManager* manager) {} 
}; 
+0

감사합니다. 나는 이것이 많은 도움이 될 거라 생각합니다 :) – Anthony