현재 다형성 유형과 할당 연산 간의 상호 작용을 조사하고 있습니다. 내 주요 관심사는 누군가가 기본 클래스의 값을 파생 클래스의 객체에 할당하여 문제를 일으킬 수 있는지 여부입니다.파생 클래스를 가리키는 참조에 대한 기본 클래스의 할당을 확인합니다.
this answer 기본 클래스의 대입 연산자는 파생 클래스의 암시 적으로 정의 된 대입 연산자에 의해 항상 숨겨집니다. 따라서 간단한 변수에 대입 할 때 타입이 잘못되면 컴파일러 오류가 발생합니다.
이class A { public: int a; };
class B : public A { public: int b; };
int main() {
A a; a.a = 1;
B b; b.a = 2; b.b = 3;
// b = a; // good: won't compile
A& c = b;
c = a; // bad: inconcistent assignment
return b.a*10 + b.b; // returns 13
}
할당이 형태의 가능성이 객체 상태를 inconcistent으로 이어질 것
는, 그러나 더 컴파일러 경고가없는 및 코드가 처음에 나에게 비 악마 같습니다 할당이 참조를 통해 발생하는 경우,이 사실이 아니다 섬광.
그런 문제를 감지 할 수있는 확립 된 관용구가 있습니까?
나는 잘못된 감지를 발견하면 예외를 던져 런타임 감지가 가능할 것으로 기대한다. 지금 생각할 수있는 최선의 방법은 기본 클래스에있는 사용자 정의 assigment 연산자입니다. 실행 시간 형식 정보를 사용하여 this
이 실제로 파생 클래스가 아닌 base의 인스턴스에 대한 포인터인지 확인한 다음 수동으로 구성원별로 사본을 만듭니다. 이것은 많은 오버 헤드처럼 들리며 코드 가독성에 심각한 영향을줍니다. 더 쉬운 것이 있습니까?
편집 : 일부 접근법의 적용 가능성은 내가하고 싶은 것에 따라 다르기 때문에 여기에 몇 가지 세부 사항이 있습니다.
나는 두 가지 수학적 개념, 예를 들어 ring과 field을 가지고 있습니다. 모든 필드는 링이지만 반대가 아닙니다. 각각에 대해 여러 가지 구현이 있으며 공통 기본 클래스, 즉 AbstractRing
및 AbstractField
을 공유합니다. 후자는 전자에서 파생됩니다. 이제는 std::shared_ptr
을 기반으로하는 쉬운 참조 작성법을 구현하려고합니다. 그래서 내 Ring
클래스에는 std::shared_ptr<AbstractRing>
구현이 포함되어 있으며이를 전달하는 많은 방법이 포함되어 있습니다. Field
을 Ring
에서 상속 받아 작성하고 싶습니다. 그런 방법을 반복 할 필요가 없습니다. 필드에 특정한 메소드는 단순히 포인터를 AbstractField
으로 캐스트 할 것이고 정적으로 캐스트하려고합니다. 나는 포인터가 실제로 건설 중 AbstractField
인지 확인할 수 있습니다. 그러나 누군가가 을 인 Ring&
에 할당 할 것이므로 걱정입니다. 따라서 포함 된 공유 포인터에 대한 내 가정 된 불변성이 깨졌습니다.
추상적이지 않은 기본 클래스가있는 것이 진짜 문제는 아닌가요? –
개인적으로 다형성 유형의 복사 생성자와 대입 연산자를 비활성화합니다. 상속 기본 다형성은 값 유형과 관련하여 실제로 잘 작동하지 않습니다. –
@OliCharlesworth : 어떻게 보이지 않습니다. 예를 들어 생각해보십시오. 버튼에서 파생 된 토글 버튼을 사용하면 기본 클래스를 인스턴스화 할 수 있어야하고 실제 세계에서 문제가 발생할 수있는 상황을 볼 수 있습니다. 그러므로 나는 모든 "추상적 인 기반이되어야한다"는 접근을 따르지 않을 것이다. 이것이 당신이 염두에 두지 않은 것이라면, 추상적 기본 수업이 어떻게 나의 상황을 도울 수 있는지 자세히 설명해주십시오. – MvG