2014-06-14 1 views
0

기본 C++ 항목을 기억하려고합니다 (오랜 시간이 걸렸습니다). 간단한 기본/자식 상속 예제를 만들었습니다. 상속 예제가 예상 결과를 출력하지 않습니다.

내가 예상 출력

대신
index 0 is 0 
index 1 is 1 
index 2 is 2 

하지만 아래 얻을 :

index 0 is 0 
index 1 is 2 
index 2 is 0 

사람은 분명히 내 부분에 가난한 실수가 무엇인지 지적 할 수 있습니까?

#include <cstdlib> 
#include <iostream> 

#include <stdio.h> 
#include <string> 
using namespace std; 

class Base 
{ 
public: 
    Base(){x=0;} 
    int x; 
}; 
class Derived : public Base 
{ 
public: 
    Derived() { y=0;} 
    int y; 
}; 

// practicing operator definition syntax 
ostream& operator<<(ostream& ostr, const Base& base) 
{ 
     ostr << base.x << endl; 
     ostr << flush; 
    return ostr; 
} 

void init(Base *b) 
{ 
    for (int i = 0; i<3; i++) 
    { 
     b[i].x=i; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    Derived arr[3]; 
    init(arr); 
    for (int idx = 0; idx< 3; idx++) 
    { 
     cout << "index is " << idx << ' ' << arr[idx] << endl; 
    } 

    return 0; 
} 
+0

'init'에 무엇을 전달하고 있습니까? – nwp

+0

분명히 잘못된 것입니다 (아래 응답 참조). – frododot

답변

5

배열 및 다형성은 C++에서 혼합되지 않습니다.

DerivedBase 개체의 크기가 다르면 프로그램에 포함 된 포인터 연산이 실패합니다.

귀하의 init 방법은 Derived 개의 개체를 Base 개의 개체로 조각입니다. 다음 할당에는 정의되지 않은 동작이 있으며, Derived 개체의 어딘가에 일부 바이트가 설정되어 있습니다.

std::vector<std::unique_ptr<B>>을 사용하는 것이 좋습니다.

또한 Base 클래스에 가상 소멸자가 없으므로 나중에 더 많은 정의되지 않은 동작이 필요합니다.

+1

+1 가상 소멸자가 없어도 문제가 없습니다. – juanchopanza

+0

"배열과 다형성은 혼합되지 않습니다 ...". 나는 이것을 알지 못했다. 배열은 배열의 첫 번째 객체에 대한 포인터 일 뿐이므로 다음과 같이 표현할 수 있습니다. Base * b = new Derived [3]; 아 .... 네가 모두 옳다. 오래 죽은 뇌 세포를 다시 생각해 주셔서 감사합니다! :-) – frododot

4

파생 유형에 대한 배열이 기본 유형에 대한 배열이 아닙니다! 파생 된 객체에 대한 포인터가 기본 객체에 대한 포인터로 변환되지만 기본 객체의 배열에 대한 포인터로 기본 포인터를 사용할 수 없습니다.

추론

은 아주 간단합니다 : 당신이 array[i] 같은 작업을 수행 할 때 컴파일러는 *(array + i)이를 변환하고 Tarray의 정적 유형이고 내부 어드레스 연산은 array + sizeof(T) * i처럼 무언가로 이루어집니다. 이제 기본 유형 B에서 파생 된 D 유형의 경우 일반적으로 sizeof(B) < sizeof(D)을 보유합니다. 따라서 파생 된 객체 배열을 기반 객체의 배열로 처리하면 인덱스 산술이 객체의 임의의 위치에서 요소에 액세스하게됩니다.

+0

예, 자리를 잡으십시오. 고맙습니다. – frododot

관련 문제