2014-11-03 1 views
1

리눅스에서 GCC를 사용하고 있습니다.정적 및 동적 바인딩이 실제로 작동하려면 어떻게해야합니까? [C++]

저는 가상 기능을 사용하는 것을 알고 싶습니다.

가상 함수 사용 여부에 관계없이 정적 바인딩과 동적 바인딩이 어떻게 발생하는지보고 이해하려면 어떤 종류의 C++ 코드를 작성해야합니까?

어떻게 그들이 최종적으로 바인딩되었는지 그리고 프로세스 중에 정확히 무슨 일이 일어 났는지 "보는"방법?

+1

정적 및 동적 연결은 가상 및 비 가상 기능과 크게 직각을 이룹니다. –

+0

@JonathanLeffler 그는 정적 대 동적 바인딩 *을 의미한다고 생각합니다. – 5gon12eder

+0

@ 5gon12eder 연결과 바인딩간에 차이점이 있습니까? –

답변

1

다음은 예입니다. 함수를 가상 함수로 설정하여이 코드를 작성하고 실행할 수 있습니다. 가상 동작, 동적 디스패치, 동적 바인딩을 얻으려면 전 처리기 매크로 IS_VIRTUAL을 정의하여 빌드하십시오. 정적 바인딩을 보려면 해당 매크로를 정의하지 않고 빌드하십시오.

#include <iostream> 

#if defined(IS_VIRTUAL) 
#define CONDITIONAL_VIRTUAL virtual 
#else 
#define CONDITIONAL_VIRTUAL 
#endif 

struct A { 
    CONDITIONAL_VIRTUAL void foo() { std::cout << "A\n"; } 
}; 

struct B : A { 
    CONDITIONAL_VIRTUAL void foo() { std::cout << "B\n"; } 
}; 

// global objects 
A a; B b; 

enum object_type { get_A, get_B }; 
A *get_object(object_type t) { 
    switch (t) { 
    case get_A: return &a; 
    case get_B: return &b; 
    } 
} 

int main() { 
    std::cout << "Choose A or B: "; 
    char c; 
    std::cin >> c; 

    A *x = get_object(c == 'A' ? get_A : get_B); 
    x->foo(); 
} 

상기 바인딩은 x->foo()의 평가와 관련있다. 컴파일러는 해당 표현식에 대해 실행할 코드를 찾아야합니다. 정적 바인딩과 동적 바인딩 모두에서 컴파일러는 x을보고 그 유형이 A*이라고보고 있으므로 struct A을보고 foo() 선언을 찾습니다. 컴파일러를 정적 바인딩으로

foo()virtual 아니라는 것을 발견, 그래서 컴파일러는 앞서가는 그 foo() 메소드를 호출하는 코드를 생성합니다. 단순한.

동적 바인딩으로

컴파일러는 virtual으로 표시하는 방법을보고하고, 따라서 컴파일러 대신에, 실행시에, 호출하는 방법을 선택할 개체 x와 연관된 함수 포인터의 테이블을 사용하는 코드를 생성하고 어떤 방법이든 찾는다. 컴파일러는 또한 다른 곳에서 코드를 생성하여 ab 전역 개체에 대한 테이블을 만듭니다. 전역 a 개체의 경우 테이블의 대상을 A::foo()으로 지정하고 b의 경우 테이블의 대상을 B::foo()으로 만듭니다. 따라서 xb 개체를 가리킨다면 테이블 검색은 B::foo()이 될 것이고 이것이 호출 될 함수입니다.

일반적으로 컴파일러는 가상 메서드가있는 모든 개체에 올바른 함수를 가리키는 테이블이 있는지 확인해야하므로 프로그램에서 개체에 대해 가상 호출을 할 수 있습니다. 런타임에 객체와 관련된 테이블을 가져 와서 호출 할 올바른 메소드를 찾으십시오.

정적 및 동적 모드에서 위의 프로그램을 빌드하고 실행 한 다음 각 입력에 대해 얻은 결과를 관찰하십시오. 입력 및 결합 유형의 각 조합에 대해 얻은 결과를 아래 표에 채우십시오.

 Binding | static  dynamic 
Input 
----- 
A     ?   ? 
B     ?   ? 

는 모든 경우에 출력은 동일한 x->foo() 메소드 호출의 평가에 의해 제조된다. 어떤 경우에 동적 인 바인딩이 있습니까? 동적 바인딩에 대한 위의 설명에 대한 이해와 일치합니까?

-1
class Base { 
public: 
    int Foo(); 
    virtual int Bar(); 
}; 

class D1 : public Base { 
public: 
    int Foo(); 
    virtual int Bar(); 
}; 

class D2 : public Base { 
public: 
    int Foo(); 
    virtual int Bar(); 
}; 

main() 
{ 
    Base * b = (rand() < 100) ? new D1 : new D2; 
    // Always calls Base::Foo() 
    b->Foo(); 
    // Call either D1::Bar() or D2::Bar() 
    b->Bar(); 
} 
+1

개체를 삭제하지 않았 으면 가상 소멸자가 없으므로 잘못되었을 수 있습니다. –

+0

@NeilKirk 입력 해 주셔서 감사합니다.하지만 질문은 바인딩에 관한 것이 었으며 완전한 클래스를 작성하는 방법이 아닙니다. 클래스가 가지고 있어야하는 모든 메소드를 추가하면 대답이 명확하지 않게됩니다. –

+1

나쁜 일이 일어나지 않도록 격려하는 "덜 명확한"대답을하는 것이 좋습니다. –

관련 문제