동적 귀속에 대한 이해를 깊이 있게 하다

3139 단어
#include <iostream>
using namespace std;
class base
{
    public:
        virtual void fun()
        {
            cout<<"base"<<endl;
        }
};
class son:public base
{
    public:
        void fun()
        {
            cout<<"son"<<endl;
        }
        void sonfun2()
        {
            cout<<"fun2"<<endl;
        }

};
void dis(base &s)
{
    s.fun();
}
int main()
{
    base *a =new son;
    a->sonfun2();
    return 0;

}

컴파일 오류:main.cpp:31:8: error: 'class base' has no member named 'sonfun2
c++ primer V4 p498:
대상, 인용이나 바늘의 정적 유형은 대상이 완성할 수 있는 행위를 결정한다. 심지어 정적 유형과 동적 유형이 같지 않을 때 기본 유형의 인용이나 바늘을 사용하면 발생할 수 있는 것처럼 정적 유형은 사용자가 어떤 구성원을 사용할 수 있는지를 결정한다.
위의 코드가 son 대상을 가리키는base 포인터(또는 인용)처럼 대상의 기본 클래스 부분만 접근할 수 있고 기본 클래스에sonfun2()가 정의되어 있지 않아서 접근할 수 없습니다.
c++ primer 4판 동적 귀속을 촉발하는 요구 p479
c++의 함수 조정 시 기본적으로 동적 귀속을 사용하지 않습니다. 동적 귀속을 터치하려면 반드시 두 가지 조건을 만족시켜야 합니다. 첫째, 허함수로 지정된 구성원 함수만 동적 귀속을 할 수 있고 구성원 함수는 기본적으로 비허함수이며 비허함수는 동적 귀속을 할 수 없습니다.둘째, 기본 유형의 인용이나 지침을 통해 함수를 호출해야 한다.(대상이 안 되면 절단이 발생합니다. 자세한 내용은 effectic++ 참조).
왜 가끔은 허석구 함수를 써야 하는지 다시 봅시다.
#include <iostream>
using namespace std;
class base
{
    public:
        virtual void fun()
        {
            cout<<"base"<<endl;
        }
        base(){}
        ~base()
        {
            cout<<"this is base"<<endl;
        }
};
class son: public base
{
    public:
        void fun()
        {
            cout<<"son"<<endl;
        }
        void sonfun2()
        {
            cout<<"fun2"<<endl;
        }
        int ss;
        son():base(),ss(5){}     // 
        ~son()
        {
            cout<<"this is son"<<endl;
        }

};
void dis(base &s)
{
    s.fun();
}
int main()
{
    base *a =new son;
    delete a;
    return 0;

}

출력은 기본 클래스의 부분으로 호출된 것이 기본 클래스의 분석 함수임을 증명한다(바늘 유형은 기본 클래스이고 분석 함수는 허점이 아니기 때문에 기본 클래스 자체의 분석 함수만 호출할 수 있기 때문이다).이때 슨의 ss멤버가 풀리지 않아 메모리 유출이 발생했다.
구문 함수를 거짓으로 선언하기
#include <iostream>
using namespace std;
class base
{
    public:
        virtual void fun()
        {
            cout<<"base"<<endl;
        }
        base(){}
        virtual ~base()
        {
            cout<<"this is base"<<endl;
        }
};
class son: public base
{
    public:
        void fun()
        {
            cout<<"son"<<endl;
        }
        void sonfun2()
        {
            cout<<"fun2"<<endl;
        }
        int ss;
        son():base(),ss(5){}     // 
        ~son()
        {
            cout<<"this is son"<<endl;
        }

};
void dis(base &s)
{
    s.fun();
}
int main()
{
    base *a =new son;
    delete a;
    return 0;

}

두 줄을 출력하면 son의 다음은base이다. (파생류의 분석 함수를 호출할 때 파생류 자체의 분석 함수를 먼저 호출하고 기류의 분석 함수를 호출한다.)
이상의 내용에 만약 잘못, 부적절한 점이 있으면 비판과 시정을 환영합니다.

좋은 웹페이지 즐겨찾기