2014-04-29 2 views
0
class Shape 
{ 
public: 
    Shape() {size=0;} 
    virtual bool isequal(const Shape& rhs){return false;}; 
    int size; 
}; 

클래스 모양을 상속받은 두 개의 클래스 (Rectangle 및 Cirle)가 있습니다.가상 클래스 및 다형성

class Circle : public Shape 
{ 
public: 
    // snip 
    Circle(int size): size(size) {} 
    Circle(const Circle & rhs): size(rhs.size){} 
    bool isequal(Shape &rhs) 
    { 
    Circle* rhsAsCircle = dynamic_cast<Circle*>(&rhs); 
    if(rhsAsCircle == nullptr) 
     return false; // not a Circle; can't be equal 
    return size==rhsAsCircle->size; 
    } 
    int size; 
}; 
class Rectangle : public Shape 
{ 
public: 
    Rectangle(int size1,int size2): size1(size1),size2(size2) {} 
    Rectangle(const Rectangle & rhs): size1(rhs.size1),size2(rhs.size2) {} 
    bool isequal(Shape &rhs) 
    { 
    Rectangle* rhs2 = dynamic_cast<Rectangle*>(&rhs); 
    if(rhs2 == nullptr) 
     return false; // not a Rectangle; can't be equal 
    return (size1==rhs2->size1 && size2==rhs2->size2); 
    } 
    int size1; 
    int size2; 
}; 

나는 벡터에서 다른 모양을 저장하고 전, 사각형/원 추가 사각형/원 삭제 (다른 : 운용을 수행하는 클래스 P를 사용합니다.

class P 
{ 
public: 
    P(){} 
    bool add(Rectangle rhs) 
    { 
    uint i=0; 
    while (i<v.size() && rhs.isequal(*v[i])==false) 
     i++; 
    if (i!=v.size()) 
     return false; 
    v.push_back(new Rectangle(rhs)); 
    return true; 
    } 
    bool add(Circle rhs) 
    { 
    uint i=0; 
    while (i<v.size() && rhs.isequal(*v[i])==false) 
     i++; 
    if (i!=v.size()) 
     return false; 
    v.push_back(new Circle(rhs)); 
    return true; 
    } 
    vector<Shape*> v; 
}; 

이 모양 (사각형 또는 원을 추가하려면) 함수를 오버로드해야만했습니다. 하나의 함수 만 수행하는 방법이 없습니까? 원 및 사각형은 모양이므로 아니기 때문에

+0

'Shape'에 추상 메소드'Shape * Clone() = 0;'을 선언하면'add()'함수에서 호출 할 수 있습니다 (그리고'Shape * 전문 수업). 그것은 당신의 벡터에있는 요소를'v.push_back (rhs.Clone());으로 밀어 넣을 것입니다. BTW 그 객체의 사본을 만들어야한다면 그 디자인을 검토 할 것입니다 ... 아마 피할 수 있습니다. –

+0

@Adriano 감사. 왜 디자인을 검토하고 무엇을 바꾸겠습니까? – bandera

+0

'Shape *'을 저장하는 이유를 모르겠지만'add()'는'Rectangle' 대신에'Rectangle'을 허용합니다. 이것은 당신이 당신의 객체 사본을 만들도록 강요합니다 ('new Rectangle (rhs)'). 물론 매개 변수가 템플릿 객체라면 실제로 복제하고 싶습니다. 그러나 방금 생성 된 것이라면 그 객체를 삭제할 것이고 유일한 목적은'add()'의 매개 변수가되는 것입니다. –

답변

1

기본 클래스 Shapeadd 함수에 전달하면됩니다. 객체에 대한 포인터 당신의 벡터 내부에 보관 vector<Shape*> v; 여기

bool add(Shape *shape) 
    { 
    uint i = 0; 

    for(i = 0; i < v.size(); i++) { 
     if(shape.isequal(*v[i]) == true) 
     return false; 
    } 

    if (i != v.size()) 
     return false; 

    v.push_back(shape); 

    return true; 
    } 

이 작동 할 방법 :

#include <iostream> 
#include <vector> 

using namespace std; 

class Shape 
{ 
protected: 
    int m_size; 
public: 
    int getSize() { return m_size; } 

    virtual bool isEqual(Shape *rhs) = 0; 
}; 

class Rectangle : public Shape 
{ 
private: 
    int m_size2; 
public: 
    Rectangle(int size, int size2) { m_size = size; m_size2 = size2; } 

    int getSize2() { return m_size2; } 

    bool isEqual(Shape *rhs) 
    { 
     Rectangle* rectangle = dynamic_cast<Rectangle*>(rhs); 

     if(rectangle == 0) 
      return false; // not a Rectangle 

     return m_size == rectangle->getSize() && m_size2 == rectangle->getSize2(); 
    } 
}; 

class Circle : public Shape 
{ 
public: 
    Circle(int size) { m_size = size; } 

    bool isEqual(Shape *rhs) 
    { 
     Circle* circle = dynamic_cast<Circle*>(rhs); 

     if(circle == 0) 
      return false; // not a Circle 

     return m_size == circle->getSize(); 
    } 
}; 

class Container 
{ 
private: 
    vector<Shape*> v; 
public: 
    ~Container() 
    { 
     for(int i = 0; i < v.size(); i++) { 
      cout << "Removind element Nr. " << i << endl; 
      delete v[i]; 
     } 
     v.erase(v.begin(), v.end()); 
    } 

    bool add(Shape *shape) 
    { 
     for(int i = 0; i < v.size(); i++) { 

      if(v[i] == shape) { 
       cout << " Element rejected (tried to add same element twice)" << endl; 
       return false; 
      } 

      if(v[i]->isEqual(shape)) { 
       cout << " Element rejected (an element with size " << v[i]->getSize() << " was already inside that list" << endl; 
       return false; 
      } 

     } 

     cout << " Adding Element" << endl; 
     v.push_back(shape); 
     return true; 
    } 

    void print() 
    { 
     for(int i = 0; i < v.size(); i++) { 
      cout << "Size of element " << i << ": " << v[i]->getSize() << endl; 
     } 
    } 
}; 

int main() 
{ 
    Rectangle *r  = new Rectangle(1, 2); 
    Circle *c   = new Circle(2); 
    Circle *c_reject = new Circle(2); 
    Rectangle *r_reject = new Rectangle(1, 2); 

    Container container; 
    container.add(r); 
    container.add(c); 

    container.add(r);  // will be rejected because r was already added 
    container.add(c_reject); // will be rejected 
    container.add(r_reject); // will be rejected too 

    container.print(); 

    return 0; 
} 
+0

왜 캐스팅해야합니까? – displayname

+0

당신은 맞습니다. 나는 기본 수업을 아이/페이스 팔에 던지려고 생각하고있었습니다. 긴 하루였습니다. – Mike

+0

그것은 일어납니다. ^^ – displayname

0

첫째, 하나의 기능을 두 add 기능을 대체 : 다음

bool add(const Shape& shape) 
{ 
    uint i=0; 
    while (i<v.size() && shape.isequal(*v[i])==false) 
     i++; 
    if (i!=v.size()) 
     return false; 
    v.push_back(shape.clone()); 
    return true; 
} 

의 구현 함수 Shape* clone()은 클래스 Shape을 상속하는 각 클래스에 있습니다.

마지막으로 순수 가상 함수 virtual Shape* clone() = 0을 클래스 Shape에 선언하십시오.