2017-11-15 1 views
1
내가 기본 클래스 모양이

을 사용 후에도 슬라이스 및 파생 클래스 원 공개적으로 Shape를 상속C++ - 객체 포인터

class Circle : public Shape 

나는 모양 포인터의 C++ 벡터를했고, 나는에 원 포인터를 할당 그들. 나는 벡터에서 Circle을 Shape이 아닌 Circle으로 취급하는 코드를 예상하여 객체 조각을 많이 읽었습니다.

출력이 주어지면 누구에게이 문제가 잘못되었음을 지적 할 수 있습니까?

int main(void) { 
vector<Shape*> shapes; 

Circle* ncl = new Circle(-8, -8, 0.2f); 
shapes.push_back(ncl); 

cout << "Expected: " << *ncl << endl; 
cout << "Reality: " << *shapes[0] << endl; 
} 

출력 : 나는 범위 중 두 클래스의 < < 연산자를 무시, 그래서 나는 그 문제가 아니라 생각하지만, 여전히

Expected: Circle is at: -8,-8 and has a radius of: 0.2 
Reality: Shape centered at point: -8,-8 

- 여기 내 재정의 코드 문맥의 :

inline std::ostream& operator<< (std::ostream& stream, const Shape& shape) { 
    std::cout << "Shape centered at point: " << shape.getX() << "," << shape.getY(); 
    return stream; 
} 

inline std::ostream& operator<< (std::ostream& stream, const Circle& circle) { 
    std::cout << "Circle is at: " << circle.getX() << "," << circle.getY() << 
     " and has a radius of: " << circle.getR(); 
    return stream; 
} 

모두 - 서클 변수가 포인터 또는 기타 형식으로 벡터에 저장되어있는 동안 내 서클 변수에 제대로 액세스 할 수 있기를 원합니다.

+0

합니까'Shape'이 ​​적어도'가상 ~ 모양() {}'소멸자? – user0042

+0

http://idownvotedbecau.se/nomcve/ – user0042

+0

실제로 서클은 그렇게합니다. –

답변

2

슬라이스가 없습니다. 단지 그 것처럼 보입니다.

오버로드는 컴파일 타임에 컴파일러가 알고있는 정적 유형에서 선택됩니다.
shapesvector<Shape*>이므로 *shapes[0]Shape&이며 과부하가 선택됩니다.

일반적인 해결책은 기본 클래스에 대해서만 operator<<을 쓰는 것입니다. 그러면 해당 개체에서 가상 함수가 호출됩니다.
이것은 동적 함수 디스패치가 런타임에 함수를 선택하게합니다. 예를 들어

:

struct Shape { virtual ostream& print(ostream& os) const { ... } }; 
struct Circle { ostream& print(ostream& os) const override { ... } }; 

ostream& operator<<(ostream& os, const Shape& s) { return s.print(os); } 
1

과부하 해결은 정적 유형으로 수행됩니다.

당신은 사용할 수 있습니다 : virtual void Shape::print(std::ostream&) const;

std::ostream& operator<< (std::ostream& stream, const Shape& shape) { 
    shape.print(stream); 
    return stream; 
} 

이 문제를 해결하기 위해.