문제

예를 들어 vtable을 검사하는 데 언어 지원이 없는 이유는 무엇입니까?멤버 함수를 새 함수로 바꿀 수 없는 이유는 무엇입니까?이러한 기능을 잘 활용할 수 있는 방법이 있다는 직감이 듭니다.

그런 일을 할 수 있는 다른 언어가 있나요?

도움이 되었습니까?

해결책

주된 이유는 vtable을 구현 세부 사항으로 유지하면 구체적인 구현이 적합하다고 판단되는 대로 이를 최적화할 수 있다는 것입니다.이는 예를 들어 다음과 같은 일이 가능하다는 것을 의미합니다.특정 메서드(또는 모든 메서드)에 대한 가상 호출이 없음을 입증할 수 있는 경우 vtable을 모두 잘라내거나 제거할 수도 있습니다.또는 vtable 디스패치를 ​​if-else 유형 확인으로 대체할 수도 있습니다.몇 가지 대안만 있음을 알 수 있습니다(이 경우 분기 예측은 작동하지만 vtable에서는 작동하지 않으며 if-else 분기가 인라인될 수 있기 때문에 유리할 수 있습니다).가장 일반적으로 호출되는 메소드가 더 일찍 나오도록 또는 일반적으로 차례로 호출되는 메소드가 캐싱을 활용하기 위해 vtable의 인접한 슬롯을 채우도록 vtable의 메소드를 재정렬할 수 있습니다.등등.물론 이러한 모든 구현은 vtable 레이아웃을 완전히 예측할 수 없게 만들어 언어 사양에 따라 구현에 노출되는 경우 쓸모 없게 만듭니다.

또한 vtable은 말처럼 간단하지 않습니다.예를 들어 컴파일러는 문제를 해결하기 위해 썽크를 생성해야 하는 경우가 많습니다. this 가상 상속이나 공변 반환 유형과 결합된 다중 상속과 같은 항목에 대한 포인터입니다.이는 이를 수행하는 "최선의 단일 방법"이 없는 것이며(이것이 다른 컴파일러가 이를 다르게 수행하는 이유입니다) 이를 표준화하려면 효과적으로 특정 방식에 대한 정착이 필요합니다.

즉, "vtable 전환"은 더 높은 수준의 구성으로 노출되는 경우(그래서 최적화가 여전히 가능함) 잠재적으로 유용한 기술입니다.예를 들어, 여러 가지를 정의할 수 있는 UnrealScript를 참조하세요. 클래스(하나는 기본값, 다른 하나는 명명됨)에 대해 명명된 상태의 일부 메서드를 재정의합니다.파생 클래스는 기존 상태에서 더 많은 메서드를 재정의하거나 자체 상태를 추가하고 재정의할 수 있습니다.또한 상태는 다른 상태를 확장할 수 있습니다. 따라서 특정 상태에 대해 메서드가 재정의되지 않으면 "부모" 상태로 돌아가고 체인이 기본 상태에 도달할 때까지 계속됩니다.액터 모델링(게임이 본질적으로 그러함)의 경우 이 모든 것이 매우 의미가 있으며, 이것이 UnrealScript에 있는 이유입니다.그리고 이 모든 것을 위한 명백하고 효율적인 구현 메커니즘은 각 상태가 별도의 vtable을 갖는 vtable 전환입니다.

다른 팁

컴파일러의 구현 세부 사항이기 때문입니다. 그 구현이 변경 될 수 있으며, 이에 의존하는 모든 코드는 연약합니다.

C ++는 사용하지 않는 것을 '지불'하지 않는 언어입니다. 이런 종류의 런타임 지원은 그 철학에 위배 될 것입니다.

이를 지원하는 많은 언어 (스펙트럼의 더 역동적 인 끝에)가 많이 있습니다.

a로 구현할 필요가 없기 때문입니다 VTable, 이것은 일반적으로 그렇습니다. 요컨대, 그런 것은 없습니다 VTable C ++에서!

JavaScript, Python 및 Ruby가 모두이 작업을 수행 할 수 있습니다. 이러한 언어에서는 클래스 및 인스턴스 정의가 런타임에 변형됩니다. 추상적으로, 각 객체와 유형은 검사하고 업데이트 할 수있는 멤버 변수 및 방법의 사전입니다.

C ++에서는 불가능합니다. 생성 된 바이너리 코드를 다시 작성할 수 있어야하므로 실질적인 성능 비용이 발생할 수 있습니다.

vtables는 일부 컴파일러에서 특정 상황에서만 존재합니다 (즉, 표준에 지정되지 않고 구현 세부 사항). 그들이 존재하는 경우에도 가상 기능이있을 때만 발생하며 다형성을 구현하기 위해 간접이 필요합니다. 이것이 필요하지 않은 경우, 그들은 최적화 될 수 있으므로 통화의 간접의 간접비를 저장합니다.

슬프게도 (또는 그렇지 않으면, 문제에 대한 견해에 따라 ;-) C ++는 원숭이 패치를 지원하도록 설계되지 않았습니다. 경우에 따라 (예 : com) vtable은 구현의 일부이며 무대 뒤에서 찌를 수 있습니다. 그러나 이것은 결코 지원되거나 휴대용이 아닙니다.

파이썬과 같은 역동적 인 언어로 그런 일을 할 수 있다고 생각합니다.

>>> class X():
...     def bar(self): print "bar"
...     
>>> x = X()
>>> x.bar()
bar
>>> def foo(x): print "foo"
... 
>>> X.bar = foo
>>> x.bar()
foo

C ++와 같은 정적 언어와의 차이점은 통역사가 런타임에 모든 이름을 찾은 다음 수행 할 작업을 결정한다는 것입니다.

C ++에는 "멤버 함수를 다른 멤버 기능으로 바꾸는"문제에 대한 다른 솔루션이있을 수 있으며, 그 중 가장 간단한 기능은 기능 포인터를 사용하는 것일 수 있습니다.

#include <iostream>

class X;
typedef void (*foo_func)(const X&);

void foo(const X&) { std::cout << "foo\n"; }
void bar(const X&) { std::cout << "bar\n"; }

class X
{
    foo_func f;
public:
    X(): f(foo) {}
    void foobar() { f(*this); }
    void switch_function(foo_func new_foo) { f = new_foo; }
};

int main()
{
    X x;
    x.foobar();
    x.switch_function(bar);
    x.foobar();
}

(Foo 및 Bar는 X & Argument를 사용하지 않습니다.이 예에서는 Python 예제와 유사합니다)

나는 vtable을 노출시키는 정적으로 편집 된 언어를 연구하고 있으며, 그것은 나를 믿습니다. 머리카락 노출.

  • C ++에서 할 수있는 일은 작은 팔꿈치 그리스로 직선 C에서 할 수 있습니다.
  • 겸손하고 합리적인 C 프로그램은 C ++로 컴파일해야합니다.

아마도 당신이 원하는 것은 C ++의 내장 시설을 사용하지 않고 자신의 VTables를 구현하는 것입니다. 당신은 포인터 투 선원 (PTMF)으로 많은 재미를 가질 것입니다!

수요가 거의없고 구현하기 쉽지 않기 때문에 Vtable 내성으로 컴파일 된 언어를 찾는 데 어려움이 있습니다. 그러나 해석 된 언어의 경우 상황은 다른 방법입니다.

내가 그런 일을 할 수있는 다른 언어가 있습니까?

Objective-C (및 Objective-C ++)는 이미 컴파일 된 메소드를 런타임 교체 할 수 있습니다. 그것은 당신이 물어 보는 사람에 따라 정적 및 동적 기술의 최상의 조합 또는 최악의 조합입니다.

다른 사람들이 지적했듯이, C ++ 표준에는 "Vtable"이라는 개념은 없습니다.

편집 된 언어로 즉시 기능을 재정의 할 수 있기를 원한다면 Common LISP에 관심이있을 수 있습니다. 다른 사람들이 있어야하지만, 내가 생각할 수있는 유일한 언어는 정적 상속과 기능을 가지고 있거나 성능이 큰 비용으로 해석됩니다.

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