허함수 용법과 주의사항 총결

일반적으로 컴파일러가 허함수를 처리하는 방법은 모든 대상에 숨겨진 구성원을 추가하는 것이다.숨겨진 함수에는 함수 주소 그룹을 가리키는 바늘이 저장되어 있습니다. 이 주소 그룹은 허함수표이고, 허함수표에는 클래스에서 설명한 허함수의 주소가 저장되어 있습니다.
클래스에 포함된 허함수가 하나든 10개든 대상에 바늘만 추가합니다. 가리키는 주소표의 크기가 다를 뿐입니다.기본 클래스에는 포인터가 허함수표를 가리키고 파생 클래스에도 포인터가 포함됩니다.
1. 파생류가 허함수를 다시 정의하지 않으면 파생류의 주소표는 기류 허함수표의 내용을 포함한다.
2, 허함수의 재정의를 제공하면 파생류의 허함수표는 새로운 주소 내용을 저장합니다.
3, 파생류에 새로운 허함수가 추가되면 새로운 함수 주소 내용은 파생류의 허함수표에 추가됩니다.
허함수표는 수조로 이루어진다. 허함수를 호출할 때 프로그램은 대상에서 바늘이 가리키는 허함수표 주소를 보고 클래스 성명에서 n번째 허함수를 호출하면 허함수표 ---주소 수조의 n번째 요소를 사용한다.
가상 함수를 사용하여 메모리와 속도 비용을 증가시켰습니다.
1, 각 객체는 하나의 포인터 크기로 크기가 커집니다.
2, 모든 클래스에 대해 컴파일러는 허함수표를 만든다(수조 실현)
3, 매번 허함수 호출 시 테이블에서 주소 찾기
 
허함수 요점
1, 기본 방법의 성명에서virtual 키워드를 사용하면 이 방법이 기본 클래스, 하위 클래스 및 하위 클래스에서 모두 허함수가 될 수 있다
2, 지향 대상의 인용과 지침을 사용하여 허위 방법을 호출하면 프로그램은 지향 대상의 유형에 따라 호출하고, 비허위 방법을 호출하면 지침이나 인용의 유형에 따라 방법을 호출한다
3, 정의된 클래스를 기본 클래스로 사용하려면 파생 클래스에서 다시 정의한 방법을 가상으로 성명해야 한다.
 
몇 가지 참고 사항:
1, 구조 함수
구조 함수는 허함수일 수 없다. 파생류의 대상이 구축될 때 자신의 구조 함수를 호출하고 기류의 구조 함수가 아니기 때문이다. 그리고 파생류의 구조 함수에서 부류의 구조 함수를 사용한다. 이것은 계승이 아니다. 파생류는 부류의 구조 함수를 계승하지 않고 구조 함수를 가상으로 성명하는 것은 의미가 없다.
2, 분석 함수
분석 함수는virtual의 파생 클래스에서 부류의 내용을 계승한다고 정의해야 한다. 만약에 부류 바늘이 하위 클래스의 대상을 가리키면 분석 함수를 실행할 때 분석 함수가 가상이 아니라면 하위 클래스의 분석 함수를 호출하면 하위 클래스가 추가한 내용을 방출할 수 없다.만약에 분석 함수를 가상으로 정의한다면 먼저 서브클래스 분석 함수를 호출하여 내용을 방출한 다음에 서브클래스 분석 함수를 호출하여 서브클래스 내용을 방출한다.
3, 유원 함수
유원 함수 는 허함수 가 될 수 없다. 왜냐하면 클래스 구성원 이 아니기 때문 에, 구성원 만이 허함수 를 만들 수 있다
4, 재정의 없음
파생 클래스가 재정의되지 않으면 기본 버전을 사용합니다
5, 숨김 방법 재정의
다음 코드를 만들었다고 가정하십시오
class base
 {
public:virtual void fun(int a);
};
class derive:public base
{
public:virtual void fun();
 
};

새로 정의된fun()는 매개 변수를 받아들이지 않는 함수입니다. 다시 정의하면 함수 두 개의 리셋 버전이 생성되지 않고 기본 클래스에서 매개 변수를 받아들이는 버전이 숨겨집니다. 쉽게 말하면 계승을 다시 정의하는 방법은 리셋이 아닙니다. 파생 클래스에서 같은 함수 특성으로 기본 클래스 성명을 덮어쓰지 않으면 같은 이름의 기본 클래스를 숨기는 방법입니다.
그래서 두 가지 경험이 있어요.
a 계승 방법을 다시 정의하려면 원래의 원형과 완전히 동일해야 하지만 반환 유형이 기본 포인터나 인용이라면 파생류를 가리키는 인용과 포인터로 수정할 수 있다. 이런 특성은 반환 유형 협동변화이다. 반환 유형이 유형의 변화에 따라 달라질 수 있기 때문이다.
class base
{
public:virtual base & fun(int a);
};
 
class derive:public base
{
public:virtual derive & fun(int a);
 
};

b 기본 클래스 성명이 다시 불러오면 파생 클래스에서 모든 버전을 다시 정의해야 합니다.
class base
{
public:virtual void fun(int a);
          virtual void fun(double x);
          virtual base & fun();
};
 
class derive:public base
{
public:virtual void fun(int a);
          virtual void fun(double x);
          virtual derive & fun();
 
};

좋은 웹페이지 즐겨찾기