2016-12-31 2 views
1

이 코드에서는 + = 기본적으로 과부하를 시도합니다. 모든 것이 비회원 파트에서 괜찮아 보이지만 멤버가 아닌 함수를 작성할 때 (이 부분에서 + 연산자) 은 잘못된 추상 반환 유형을 잘못 나타내며 + = operation이 vector1d 내에서 순수하다고 말합니다. 이 문제를 어떻게 해결할 수 있습니까? AbstractBase재정의 된 함수를 사용하는 비 멤버 함수를 만들려면 어떻게해야합니까?

Vector1d &operator+=(const Vector1d &other);

에서

class AbstractBase{ 
     public: 
     virtual AbstractBase &operator+=(const AbstractBase &other)=0; 

     private: 
     } 
    //// 
     class Vector1d:public AbstractBase{ 
     public: 
     Vector1d &operator+=(const Vector1d &other); 

     private: 
      int size_; 
      vector<double> data_; 

     } 
     //non member func 
     Vector1d operator+(const Vector1d& vec1, const Vector1d& vec2); 


     /// 


     Vector1d &Vector1d::operator+=(const Vector1d &other){ 
       cout<<"sum operator is called"<<endl; 
       for(int i = 0; i < other.size_ ; i++) 
       data_.at(i) += other.data_.at(i); 
       return *this; 
      } 

     Vector1d operator+(const Vector1d& vec1, const Vector1d& vec2){ 
     return (Vector1d) vec1 += vec2; 
     }; 
+0

운영자가 순수 가상이 될 수 있습니까? – Bcan

+0

문제는 연산자 + = (AbstratctBase)와 연산자 + = (Vector1d)가 다른 서명을 가지므로 후자는 첫 번째를 재정의하지 않는다는 것입니다. – z32a7ul

+0

가상 함수의 반환 유형 만이 공변이지만 인수 유형이 아닙니다. –

답변

5

재정의 할 때 C++ 11 override 문맥 키워드를 사용하십시오. 그러면 실수를 한 곳으로 오류가 옮겨집니다. 그게 당신이 오버라이드하지 않은 것입니다.

다른 곳에서는이 사실을 알 수 있지만 혼란 스럽습니다.

이 :

virtual AbstractBase &operator+=(const AbstractBase &other)=0; 

이 아닌 다른 서명했습니다

Vector1d &operator+=(const Vector1d &other); 

을 그리고 두 번째는 첫 번째 우선하지 않습니다. 그것은 단지 과부하입니다. (그들은 다릅니다!)

기본적으로 설계에 근본적인 오류가 있음을 나타내는 LSP (see here)를 위반하고 있습니다. 그 문제를 해결하는 방법에 대한 정보가 부족합니다. LSP 위반으로 인해 빌드가 끊어지는 것은 아닙니다.

이 빌드 휴식을 해결하려면 수행

Vector1d &operator+=(const AbstractBase &other) override; // and maybe final 

(반환 유형이 정확히 일치하지 않는,이 괜찮습니다, 때문에 C에서 공변 반환 형식 규칙의 override 키워드 그것을 확인, ++. 공분산은 어떤 의미있는 언어로도 적용될 수는 없지만 (C++은 공짜로 제공하지 않으며 어쨌든 그렇게하지 않으려 고합니다), 공감은 const& 인수에 적용되지 않습니다.)

그리고 몸에 :

Vector1d &Vector1d::operator+=(const AbstractBase &other_abstract){ 
    auto& other = dynamic_cast<Vector1d const&>(other_abstract); // can throw 
    std::cout<<"sum operator is called"<<std::endl; 
    for(int i = 0; i < other.size_ ; i++) 
     data_.at(i) += other.data_.at(i); 
    return *this; 
} 

이 이제 추상 형식이 예상 유형과 일치하지 않는 경우 나쁜 캐스트가 발생합니다. 어느 것이 끔찍한가요?

LSP 오류는 추상 기본 +=이 동일한 추상 기준을 가진 두 개의 객체가 += '일 수 있음을 의미합니다. 귀하의 구현은 매우 현명하게 동의하지 않습니다. 이것은 여러분의 계급 계층이 쓰레기이며, 버려지고 교체되지 않아야 함을 의미합니다. 하지만 그것은 기술 빌드 틈에 대한 SO 답변에서 다룰 수있는 것보다 광범위한 문제입니다.

3

하더라도 Vector1d 상속은 결과적으로는 재정의 후보가 될 수 없습니다

AbstractBase &operator+=(const AbstractBase &other)=0

과 동일한 서명이 없습니다.

4

기본적으로 operator+=(const AbstractBase &other)을 덮어 쓰지 마십시오.

const Vector1d&을 사용하는 새로운 operator+=을 제공하지만 +=에서만 파생 형식을 사용할 수 있습니다.

기본 클래스 연산자 +=은 모두 AbstractBase과 함께 사용할 수 있으므로이 값을 덮어 쓰면 파생 된 구현이 AbstractBase과 함께 작동하도록 서명을 보존해야합니다.

이것은 클래스 계층에 적합하지 않을 수 있으므로 추상 기본 클래스 'operator+=의 유틸리티에 대해 신중하게 생각하십시오.