2011-11-22 7 views
1

다음 코드기준 변수 및 상속

#include <stdio.h> 
class Parent 
{ 
public: 
    virtual void func() {printf("Parent\n");} 
}; 

class Child1 : public Parent 
{ 
    virtual void func() {printf("Child1\n");} 
}; 

class Child2 : public Parent 
{ 
    virtual void func() {printf("Child2\n");} 
}; 

int main(int argc, char* argv[]) 
{ 
    Parent & obj = Child1(); 
    obj.func(); 
    obj = Child2(); 
    obj.func(); 
    return 0; 
} 

다음과 같은 결과를 얻을 :

expected: Child1 Child2. 

actual: Child1 Child1. 

(VS2010 컴파일)에 vptr에서의 할당에 의해 변경되지 않도록

I 추측 . 거기에 그것을 다시 (부모에 대한 포인터를 사용하고 그것을 사용하여 새를 사용하여 이외의) 만들 수있는 방법은?

감사

+6

참고 문헌은 다시 채울 수 없습니다. 게다가 임시 변수는 상수가 아닌 참조에 바인딩 될 수 없습니다. 귀하의 코드가 부적절합니다 –

+2

왜 처음부터 참조로이 작업을 수행해야합니까? 'obj'를 변경하면, 그것을 객체 나 포인터로 만드십시오. – leftaroundabout

+1

이것은 컴파일되지 않습니다! 여기에 실제 코드를 게시하십시오. –

답변

3

입력 자식 2의 인수와 함께, 여전히 타입 자식 1의 인 OBJ의 기본 할당 연산자를 호출하고 있습니다. 개체 자체는 여전히 Child1입니다. 모든 클래스에 operator =을 구현하고 거기에 print 문을 삽입하여이를 확인할 수 있습니다.

+0

감사합니다. ref var에 다형성을 사용하는 방법이 있습니까? – OSH

+0

@OrenS. 다형성을 사용 중입니다. 이것이 Child1 :: func에 대한 호출이 작동하는 이유입니다. 하지만 Child2 유형이지만 Child1 유형의 객체는 없습니다. –

+3

할 수있는 유일한 방법은 ** 리 바인드 ** 다형성입니다. 잘만되면 분명히 스마트 포인터를 사용하는 것이 좋습니다. – moshbear

1

참조를 다시 사용할 수 없습니다. 참조 된 개체는 전체 수명 동안 동일한 개체를 나타냅니다. 참조하는 객체를 변경할 수있는 무언가가 필요하다면 참조 대신 [스마트] 포인터를 사용해야합니다.

여기에서 수행하는 작업은 Child1의 인스턴스에 이라는 인스턴스를 할당하여 slicing 인스턴스입니다.

1
Parent & obj = Child1(); 

Child1 유형의 개체에 대한 참조를 만듭니다. 이

Child1 c1; 
Parent& obj = c1; 

obj 지금 형 Child1의 목적은 c1 단지 다른 이름입니다 말하는 것과 같다.

obj = Child2(); 
obj.func(); 

지금이

c1 = Child2(); 
c1.func(); 

은 그래서 당신은, 당신은 여전히 ​​유형 Child1의 객체에 func를 호출하고 참조 말하는 것과 같다.

0

컴파일 중 오류가 발생해야합니다. 임시 변수 (Child2()으로 작성)를 참조 변수에 지정할 수 없습니다. Child2 이전에 인스턴스를 만들고 해당 변수를 경의에 지정해야합니다.

+0

제 컴파일러가 동의하지 않습니다 ... – OSH

+0

@OrenS. 나는 오류를 잘못 읽었고 실제로는'Parent & obj = Child1();'행에서 오류가 발생합니다. –

+1

'g ++'는 이것을 컴파일하지 않지만, 물론'Child1' 타입의 변수를 만들고 거기에서 할당 할 수 있습니다. VS2010이 이것을 처음부터 컴파일한다는 것을 매료시킵니다. – hochl

1

C++의 두 가지 기본 속성 : 한 번 생성 된 개체. 절대로 이 형식을 변경하지 않고 초기화되면 참조가 항상 같은 개체를 참조합니다.

는 여기에서 무슨 일이 일어나고하면 컴파일러는 당신이 원하는 무엇을 거의 확실하지 않은, Parent에 대한 operator= 가상이 아닌 공급 요구하고 있다는 점이다. 그러나보다 일반적으로는 할당 및 상속이 과 함께 작동하지 않습니다 (정확히 객체의 유형을 변경할 수 없기 때문입니다). 대부분의 경우 상속을 사용할 때 지정을 금지해야합니다 (예 : boost::noncopyable에서 상속). 글자/봉투 관용구를 사용하여 다형성 클래스에 대한 값 의미를 구현할 수있는 것은 이지만 무거운 해결책이며 거의 은 적합하지 않습니다.

(난 당신의 코드는 C++ 컴파일러로 컴파일되지 않음을 추가 할 수 있습니다. 당신은이 마이크로 소프트 확장 허용. 법적 C++이 아닌 일시적인와 const가 아닌 참조를 초기화 있어 .)