10.3. 프로그램언어 C++에서의 가상 함수

프로그램언어 C++의 가상 함수의 기본 개념

가상 함수는 C++에서 다형성(polymorphism)을 구현하기 위한 중요한 개념입니다. 가상 함수를 사용하면 동일한 함수 호출이 서로 다른 클래스에서 다르게 동작하도록 할 수 있습니다. 이는 상속 관계에 있는 클래스들 간에 유용하게 활용됩니다.

가상 함수를 선언하기 위해서는 부모 클래스에서 해당 함수를 가상 함수로 선언해야 합니다. 파생 클래스에서는 부모 클래스의 가상 함수를 오버라이딩(재정의)하여 자신에 맞는 동작을 구현할 수 있습니다. 이렇게 하면 프로그램이 실행될 때 객체의 실제 타입에 따라 적절한 함수가 호출됩니다.

가상 함수는 부모 클래스의 포인터나 참조를 통해 파생 클래스의 객체에 접근할 때 특히 유용합니다. 이를 통해 동적 바인딩(dynamic binding)이 가능해지며, 실행 시간에 객체의 실제 타입을 확인하여 적절한 함수를 호출할 수 있습니다.


#include <iostream>

class Animal {
public:
    virtual void makeSound() {
        std::cout << "Animal makes a sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Dog barks" << std::endl;
    }
};

int main() {
    Animal* animal = new Dog();
    animal->makeSound(); // Dog의 makeSound() 함수가 호출됨
    delete animal;
    return 0;
}

프로그램언어 C++에서의 가상 함수의 작동 원리

가상 함수는 C++에서 다형성(polymorphism)을 구현하기 위한 중요한 개념입니다. 가상 함수를 사용하면 동일한 함수 호출이 서로 다른 객체에 대해 다른 동작을 수행하도록 할 수 있습니다. 이를 통해 객체 지향 프로그래밍의 핵심인 추상화와 상속을 구현할 수 있습니다.

가상 함수의 작동 원리는 가상 함수 테이블(virtual function table, vtable)을 통해 이루어집니다. 각 클래스에는 가상 함수를 가리키는 vtable이 생성되고, 객체가 생성될 때마다 해당 클래스의 vtable을 가리키는 포인터가 객체 내에 생성됩니다. 이를 통해 가상 함수 호출 시 해당 객체의 vtable을 참조하여 실제 호출할 함수를 결정합니다.

아래는 C++에서 가상 함수의 작동 원리를 보여주는 간단한 예제 코드입니다.


#include <iostream>

class Animal {
public:
    virtual void makeSound() {
        std::cout << "Animal makes a sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Dog barks" << std::endl;
    }
};

int main() {
    Animal* animal = new Animal();
    Animal* dog = new Dog();

    animal->makeSound();  // "Animal makes a sound"
    dog->makeSound();     // "Dog barks"

    delete animal;
    delete dog;

    return 0;
}

프로그램언어 C++의 가상 함수의 사용 예제

가상 함수는 C++에서 다형성(polymorphism)을 구현하는 중요한 개념 중 하나입니다. 가상 함수를 사용하면 부모 클래스의 포인터나 참조를 통해 서브 클래스의 함수를 호출할 수 있습니다. 이를 통해 런타임에 객체의 실제 타입에 따라 다른 함수가 호출될 수 있습니다.

가상 함수를 사용하는 예제를 살펴보겠습니다. 아래의 코드는 동물을 나타내는 `Animal` 클래스와 그를 상속받는 `Dog`와 `Cat` 클래스가 있습니다. `Animal` 클래스에는 `makeSound`라는 가상 함수가 정의되어 있습니다. 각 서브 클래스에서는 이 함수를 오버라이딩하여 해당 동물의 울음 소리를 출력하도록 구현합니다.


#include <iostream>

class Animal {
public:
    virtual void makeSound() {
        std::cout << "Animal makes a sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Dog barks" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        std::cout << "Cat meows" << std::endl;
    }
};

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();

    animal1->makeSound(); // Dog barks
    animal2->makeSound(); // Cat meows

    delete animal1;
    delete animal2;

    return 0;
}

위의 예제에서 `Animal` 클래스의 `makeSound` 함수가 가상 함수로 선언되어 있기 때문에 `Dog`와 `Cat` 클래스에서 이 함수를 오버라이딩할 수 있습니다. 따라서 `Animal` 포인터를 사용하여 `Dog`와 `Cat` 객체를 가리키고 있을 때, 각 객체의 실제 타입에 맞게 적절한 함수가 호출됩니다.

프로그램언어 C++에서의 가상 함수의 장단점

가상 함수는 C++에서 다형성을 구현하는 중요한 개념입니다. 가상 함수의 장단점은 다음과 같습니다.

장점:

1. 다형성 구현: 가상 함수를 사용하면 상속 관계에서 서브클래스에서 부모 클래스의 함수를 오버라이딩하여 다형성을 구현할 수 있습니다.

2. 유연성: 런타임 다형성을 제공하여 프로그램이 실행 중에 객체의 실제 타입에 따라 적절한 함수가 호출됩니다.

3. 확장성: 새로운 클래스를 추가하거나 기존 클래스를 수정할 필요 없이 다형성을 활용하여 기능을 확장할 수 있습니다.

단점:

1. 성능 저하: 가상 함수 호출은 가상 함수 테이블(Virtual Table)을 통해 이루어지므로 일반 함수 호출보다 성능이 느릴 수 있습니다.

2. 오버헤드: 가상 함수를 사용하면 추가적인 메모리 공간이 필요하고 가상 함수 테이블을 관리하는 오버헤드가 발생할 수 있습니다.

3. 오버라이딩 오류: 가상 함수를 오버라이딩할 때 실수로 함수 시그니처를 변경하면 예기치 않은 동작이 발생할 수 있습니다.

예제 코드:


#include <iostream>

class Animal {
public:
    virtual void makeSound() {
        std::cout << "Animal makes a sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Dog barks" << std::endl;
    }
};

int main() {
    Animal* animal = new Dog();
    animal->makeSound(); // 다형성을 통해 Dog 클래스의 makeSound 함수가 호출됨
    delete animal;
    return 0;
}

프로그램언어 C++의 가상 함수와 다른 함수와의 차이점

가상 함수와 다른 함수의 주요 차이점은 다음과 같습니다.

1. 가상 함수

가상 함수는 기반 클래스에서 파생 클래스에서 재정의(override)될 수 있는 멤버 함수입니다. 이를 통해 다형성(polymorphism)을 구현할 수 있습니다.

2. 다른 함수

다른 함수는 일반적인 멤버 함수로, 재정의되지 않고 그대로 사용됩니다.

아래는 C++에서 가상 함수와 다른 함수의 예제 코드입니다.


#include <iostream>

class Base {
public:
    // 가상 함수
    virtual void virtualFunction() {
        std::cout << "Base의 가상 함수" << std::endl;
    }

    // 다른 함수
    void normalFunction() {
        std::cout << "Base의 다른 함수" << std::endl;
    }
};

class Derived : public Base {
public:
    // 가상 함수를 재정의
    void virtualFunction() override {
        std::cout << "Derived의 가상 함수" << std::endl;
    }

    // 다른 함수를 재정의하지 않음
};

int main() {
    Base* basePtr = new Derived();
    
    // 가상 함수 호출
    basePtr->virtualFunction();
    
    // 다른 함수 호출
    basePtr->normalFunction();
    
    delete basePtr;
    return 0;
}

Leave a Comment