2009-02-05 3 views
0

다음 클래스가 있습니다.전화 기본 클래스 함수

class A 
{ 

public: 

void fun(); 

} 

class B: public A 
{ 

} 

class C: public A 
{ 

} 

A * ptr = new C; 

다음과 같이하면 되나요? baseclass에 몇 가지 가상 함수를 도입하면 몇 가지 문제가 있습니까?

((B *)ptr)->fun(); 

이것은 어리석은 것처럼 보일 수 있지만 B를 통해 A의 기능을 호출하는 기능이 있으며 변경하고 싶지 않습니다.

+0

예가 다소 모호합니다. B와 C가 재미를 재정립합니까? 실제로 컴파일되는 코드를 게시 할 수 있습니까? 예를 들어, ((B *) ptr) -> fun()를 써야만한다. 그렇지 않으면 함수의 반환 값을 B *로 변환한다. –

+0

"B를 통해 A의 함수를 호출하는 함수가 있습니다."는 실제로 의미합니다. 전화 해줘? 이것은 디자인이 실패한 것처럼 보입니다. –

+0

코드에 뭔가 해킹하려고 시도하는 대신 모델을 다시 생각해야한다고 생각합니다. 예를 들어, 호출하려는 코드가 A에서 구현되지 않고 B에서 구현되는 이유는 무엇입니까? –

답변

7

클래스 C는 클래스 B와 관계가 없으므로 클래스 C에 B *로 캐스팅 할 수 없습니다. 정의되지 않은 동작이 발생하여 잘못된 호출이 발생하고 스택 손상이 발생할 수 있습니다 .

클래스 C가 클래스 B에서 파생되도록하려면 다음을 수행 할 수 있습니다. 그러나, 당신은 필요가 없을 것입니다. C 클래스에 fun()가 정의되어 있지 않으면 A 클래스를 상속받습니다. 당신은 fun()를 선언하지 않았지만 C :: fun() 나 B :: fun()를 구현해도 이상한 동작을 보일 것이다. 거의 확실히 fun()가 가상으로 선언되기를 원합니다.

+0

사실 C++에 대한 아름답고 끔찍한 것들 중 하나 인 B *로 A *를 가리키는 A * 캐스팅을 할 수 있습니다. 확실히 좋은 생각이 아닙니다. –

+0

정확합니다.그것은 가능하지만, 내가 지적한대로 당신은 아마도 스택 손상을 가져올 것입니다. 어쩌면 내가 말 했어야했는데, "너는 안전하게 * 캐스팅 할 수 없다 ..." –

+0

정말로 헤링 스팅. 1/0을 쓸 수도 있지만, 여전히 0으로 나눌 수있는 것은 아닙니다. – MSalters

0

캐스팅 (B *)을 수행 할 필요가 없습니다. ptr-> fun(); fun()가 이미 기본 클래스에 있으므로 클래스 B 또는 C의 두 객체는 ​​예제에서 동일한 fun() 함수를 호출합니다. 내가 u는 클래스 B의 재미() 함수를 오버라이드 (override) 할 경우에 어떻게되는지 확실하지 않다

...

그러나 다른 클래스 (안 기본 클래스)에서 함수를 호출하려고 나쁜 OO 내 의견에서, .

+0

C가 A에서 파생 되었기 때문에 그가 가지고있는 것은 정확합니다. 그래서 (A *) 로의 캐스트는 불필요합니다. –

0

여기서 추측하고 있지만이 동작은 사용하는 컴파일러와 vf 포인터 테이블을 구성하는 방법에 따라 다를 수 있습니다.

나는 또한 당신이하고있는 일이 나쁜 생각이며 모든 종류의 악몽 같은 문제 (static_cast와 dynamic_cast 같은 것을 사용하는 것이 일반적으로 좋은 아이디어 임)로 이어질 수 있다고 생각할 것입니다. 다른 하나는 기본 클래스에서 fun()가 정의 되었기 때문입니다. ptr-> fun()는 B *로 변환하지 않고 항상 A :: fun()를 호출합니다.

0

A *에서 B *로 캐스트 할 수 있으며 원래 포인터가 B * 인 경우 작동합니다.

A* p = new B; 
B* q = static_cast<B*>(p); // Just work (tm) 

그러나이 경우에는 C의 *이며, 그것은 당신이 액세스 위반을 얻을 것이다 운이 아닌 경우 당신이 사람이 결국, 당신이, 매달려 포인터로 끝납니다 작동하지 않을 수있다 조용히 당신의 기억을 망치고.

A* p = new C; 
B* q = static_cast<B*>(p); // Owned (tm)