문제

기능 이동으로 Vir라는 클래스를 만들었습니다.

class vir
{
public:
     vir(int a,int b,char s){x=a;y=b;sym=s;}
     void move(){}
};

(변수 in x, int y 및 char sym이있는 클래스에서 파생되었습니다.

class subvir:public vir
{
public:
     subvir(int a,int b,char s){x=a;y=b;sym=s;}
     void move();
};
subvir::move()
{
     x++;
     return;
}

그런 다음 VIR 배열을 만들어 서브 바이어를 넣었습니다.

subvir sv1(0,0,'Q');
vir vir_RA[1]={sv1};

그러나 sv1.move ()를 사용하려고 할 때 :

vir_ra [0] .move ();

서브 바이어 이동 ({x ++}) 대신 vir move ({})를 사용합니다. 나는 sv1을 vir와 vir_ra를 Vir로 만들려고 시도했고, 그것은 작동하며, 그것들을 모두 서브 바이어로 만들 때 작동하지만, 나는 그것들이 달라야합니다. Vir :: Move ()를 순수한 가상으로 만들려고했지만 배열을 입증하는 오류가 발생합니다. 배열에서 사용할 때 Move ()가 작동하는 방법을 아는 사람이 있습니까?

도움이 되었습니까?

해결책

이 경우 인스턴스가 아닌 다양한 포인터가 필요합니다. vir [] 대신 vir*[]를 사용하십시오.

다른 팁

당신은 불리는 문제에 빠지고 있습니다 슬라이스. 포인터 또는 같은 배열을 사용하십시오 boost.ptr_container.

기본 클래스에는 있어야합니다 virtual 당신이 원하는 것을 얻는 기능, 이러한 순수하게 만들면 추상적 인 기본 클래스가 생성됩니다. 그러나 추상 기본 클래스에 대한 포인터/참조를 만들고 파생 클래스 객체를 할당 할 수 있습니다. 기본 클래스는 다음과 같이 가장 잘 표현됩니다.

class vir
{
public:
     vir(int a,int b,char s){x=a;y=b;sym=s;}
     virtual void move(){}
};

이것은 파생 클래스를 만듭니다 move 가상. 그러나 당신의 move 정의에는 반환 값이없고 컴파일하지 않습니다. 노력하다:

void subvir::move()
{
     x++;
     return;
}

포인터 (다른 답변에 언급 된 바와 같이) 또는 작업에 대한 동적 바인딩에 대한 파생 클래스에 대한 참조가 필요합니다. 따라서 배열 대신 vir 개체, 기본 클래스 포인터 배열 사용 :

vir* v[ 2 ] = { new subvir(0, 0, 'Q'), new subvir(10, -10, 'P') };

C ++ FAQ 라이트의 다음 섹션에서도 읽어야합니다.

두가지. 배열은 Vir의 배열이므로 물론 Vir :: Move를 사용합니다. Move ()는 가상 방법이 아닙니다.

그러나 더 중요한 것은 슬라이스입니다. 서브 클래스를 배열에 넣을 수 없습니다. vir! = size의 size의 size의 size는 배열이 올바르게 정렬되지 않습니다. 현재 그들은 같은 크기입니다. 그러나 그렇지 않으면 어떻게 되는가.

예, 기본적으로 컴파일러는 배열이 유형 크기에 대해 단단히 초기화되고 하위 유형은 부모보다 큰 경향이 있고 하위 유형 값으로 배열을 초기화 할 수있는 경우 문제를 초래할 수 있기 때문에 배열에서 서브 클래스를 허용하지 않습니다. 실제로 발생하는 것은 컴파일러가 먼저 배열 n * size (base_type) 바이트를 할당합니다. 그런 다음 각 초기화 객체의 크기 (base_type) 바이트를 복사합니다. 그들이 다른 유형이라면, 그들은 잘라 내고 코드에서 이상한 일이 일어날 수 있습니다.

이전 답변을 통합하겠습니다.

실제로 여기에는 두 가지 문제가 있습니다. 하나는 슬라이스하고 있습니다. Subvir의 사본으로 Virs 배열을 초기화하고 있습니다. 이러한 경우 컴파일러는 바이러스 부품을 서브 바이어에서 깎아서 배열에 복사하므로 Vir 객체 만 실제로 얻을 수 있습니다. 이제 특정 경우 Subvir에는 VIR 이외의 추가 데이터 구성원이 없으므로 슬라이싱은 다소 퇴화되고 VIR 객체는 Subvir과 비슷합니다. 그러나 Vir와 Subvir는 다른 클래스이며 배열의 객체는 vir 객체가되고 vir로 위장한 하위 바이어 객체가 아닙니다. 두 가지 데이터 구성원이 동일한 경우에도 Vir가 Subvir에 의해 과부하 된 가상 함수가있는 경우에도 실제로 두 가지의 차이가 실제로 나타납니다. 이 경우 배열의 객체의 vtable 포인터는 서브 바이어가 아닌 Vir의 vtable을 가리 킵니다. 물론 Subvir에 VIR에서 찾을 수없는 추가 데이터 구성원이 포함되어 있으면 더욱 명백 할 것입니다.

두 번째 문제는 다형성입니다. 사용 지점 (Move to Move ())에서 컴파일러는 Vir 유형의 객체의 Move () 메소드를 호출한다고 생각합니다 (배열은 Virs 배열이므로). (컴파일러는 당연히 생각할 때 맞습니다.이 경우 슬라이싱으로 인해이 경우에 퇴보 할 수 있습니다.) 실제로 의도 한대로 하위 바이어 객체가되면 Make Make (Make Make) (Subvir :: Move)를 얻을 수 있습니다 (). ) VIR의 가상.

원하는 동작을 얻으려면 다양한 포인터 배열을 사용할 수 있습니다 (그러나 사본을 처음 작성하고 사본에 대한 포인터로 배열을 초기화하지 않는 한 사본이 아닌 SV1에서 직접 작동합니다).

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