머리말
- 상속 계층에 도입 점에서 (36), 유도 클래스 바람직 닫기 만이 아닌 가상베이스 클래스로 이동하지 않고 가상 함수를 오버라이드 커버
- 따라서, 소개하는이 절은 "기본 매개 변수 값이 상속 재정의하지 않음" 의 관점에서 가상 함수입니다
- 중요한 개념 : 가상 함수는 동적으로 바인딩되지만, 기본 매개 변수 값 가상 함수는 정적 바인딩
첫째, 정적 유형 및 동적 유형
- 정적 유형 : 에 의해 채택 된 선언의 유형
- 동적 유형 : 현재의 지식 객체 유형
사례 발표
class Shape {
public:
enum ShapeColor { Red, Green, Blue };
virtual void draw(ShapeColor color = Red)const = 0;
};
class Rectangle :public Shape {
public:
virtual void draw(ShapeColor color = Green)const = 0;
};
class Circle :public Shape {
public:
virtual void draw(ShapeColor color)const = 0;
};
![](https://img-blog.csdnimg.cn/20200312200302969.png)
- 이제 우리는 다음과 같은 코드를 정의, 그들은 그들이 가리 상관없이 그래서, 정적 형식은 모양입니다 *, 핀터 - 투 - Shpae 유형으로 선언된다 :
Shape* ps; //静态类型为Shape*
Shape* pc = new Circle; //静态类型为Shape*
Shape* pr = new Rectangle; //静态类型为Shape*
- 어떤 행동이있을 것이다 오브젝트 수단의 동적 유형입니다. 예를 들면 :
Shape* ps;
Shape* pc = new Circle;
Shape* pr = new Rectangle;
ps = pc; //ps的动态类型如今是Circle*
ps = pr; //ps的动态类型如今是Rectangle*
- 우리는 가상 함수를 호출하는 구문에 따라 동적 유형에 따라 결정된다는 것을 알고있다. 예를 들면 :
Shape* ps;
Shape* pc = new Circle;
Shape* pr = new Rectangle;
pc->draw(Shape::Red); //调用Circle::draw(Shape::Red)
pr->draw(Shape::Red); //调用Rectangle::draw(Shape::Red)
둘째, 기본 매개 변수는 가상 함수는 정적 바인딩 값
- 가상 기능에 대한 가상 동적 바인딩 기능을하지만, 기본 매개 변수 값을 호출하는 시간은 정적으로 바인딩되어 있지만
- 다음 코드를 참조하십시오 :
- 우리는 가상 함수는 동적 바인딩 것을 알고있다 () 호출이 직사각형 :: 그릴 그래서, 홍보 사각형의 동적 유형을
- 그러나 가상 기본 매개 변수 값을 정적 바인딩 기능이다 매개 변수없이 위의 클래스 무승부의 정의에서 사각형 () 함수,하지만 인해 모양 포인터 홍보 정적 유형, 추첨 () 함수의 기본 매개 변수 값 때문에 그것은 모양에 대한 매개 변수 값의 형태 :: 무승부 () 함수 :: 레드
Shape* pr = new Rectangle;
pr->draw(); //调用的是Rectangle::draw(Shape::Red)
//Circle也是相同的道理
Shape* pc = new Circle;
pc->draw(); //调用的是Circle::draw(Shape::Red),而不是Circle::draw(Shape::Green)
- 왜이 동작을 설계 : 운영 효율성이. 기본 매개 변수 값이 동적 바인딩 경우, 컴파일러는 현재 위치에 느린 더 복잡한 "컴파일 타임에 결정에서"메커니즘보다 런타임에 가상 함수에 해당하는 매개 변수의 기본 값을 확인 할 수있는 방법이어야합니다
셋째, 상속의 기본 매개 변수 값을 다시 정의하지 않습니다
- 둘째, 우리는 알고 기본 매개 변수는 가상 함수는 정적 바인딩 값. 가상 함수를 호출 할 때 예기치 않은 결과 때문에 따라서, 우리는 기본 매개 변수 값이 상속 재정의하지 않습니다 (코드는 PC로 무승부를 (호출 이상은) 예입니다)
주어진 넷째, 기본 매개 변수 값 가상 함수의 권장 사항에 대한 응답,
비효율적 인 프로그램보기
- 기본 클래스 일관성 파생 클래스 및하는 비효율적 인 방법으로 가상 함수 일관성 디폴트 파라미터 값을 설정하고 기본 클래스 유래
- 예를 들면 :
class Shape {
public:
enum ShapeColor { Red, Green, Blue };
virtual void draw(ShapeColor color = Red)const = 0;
};
class Rectangle :public Shape {
public:
virtual void draw(ShapeColor color = Red)const;
};
class Circle :public Shape {
public:
virtual void draw(ShapeColor color = Red)const;
};
- 비효율적 인 이유 :
- ① 코드 중복
- ② 의존은 기본 클래스의 기본 매개 변수 값이 변경된 경우, 당신은 다시 수정 된 기본 매개 변수 값 파생 클래스가 필요, 너무 높은
클래스를 정의하는 NVI는 방법
- 항목 36 피하기 기본 매개 변수의 기본 클래스에 순서대로 소개합니다 기본 매개 변수 값 virutal 기능에 대한 NVI 기술 및 파생 클래스의 값은 우리가이 방법을 취할 수, 일치하지 않는
- 코드를 다음과 같이 정의된다 :
class Shape {
public:
enum ShapeColor { Red, Green, Blue };
void draw(ShapeColor color = Red)const { //因为是non-virtual函数,因此不建议派生类隐藏
doDraw(Red);
}
private:
//真正的工作在此处完成,派生类可以重写
virtual void doDraw(ShapeColor color)const = 0;
};
class Rectangle :public Shape {
private:
virtual void doDraw(ShapeColor color)const = 0;
};
- doDraw 위 () 함수는 실제 함수를 완료하고 유형 ShapeColor을 허용하는
- 우리는 레드에 그것의 매개 변수 기본값이 아닌 가상 함수 무승부를 정의하고, 비 가상 함수 때문에, 숨기기에 파생 클래스를 권장하지 않습니다 () 기본값이 매개 변수는 항상 레드 것, 기능이 기본 클래스 또는 파생 클래스가 무승부를 호출 여부 우리의 궁극적 인 목표를 달성하기 위해
V. 요약
- 당신이 커버해야 할 유일한 것은 - - 그것은 동적 바인딩은 절대로 기본 매개 변수 값을 정적 바인딩 및 virutal 기능이기 때문에, 상속의 기본 매개 변수 값을 재정의하지