C++

C++ 순수 가상 함수와 추상 클래스 총정리

김구티2 2024. 4. 15. 19:01

1. 순수 가상 함수와 추상 클래스의 개념

기본 클래스에서는 모든 함수의 구현을 알 수 없기 때문에 모든 함수의 구현을 제공할 수 없는 경우가 있다. 이러한 클래스를 추상 클래스라고 한다. 예를 들어 Shape을 기본 클래스라고 하자. Shape에서 함수 draw()의 구현을 제공할 수는 없지만, 파생된 모든 클래스에는 draw()의 구현이 있어야 한다는 것을 알고 있다. 마찬가지로 Animal 클래스에는 move()의 구현이 없지만(모든 동물이 움직인다고 가정할 때), 모든 동물은 움직이는 방법을 알고 있어야 한다. 우리는 추상 클래스의 객체를 만들 수 없다.

C++의 순수 가상 함수(또는 추상 함수)는 구현할 수 있는 가상 함수이지만, 파생 클래스에서 해당 함수를 재정의해야 하며, 그렇지 않으면 파생 클래스도 추상 클래스가 된다. 순수 가상 함수는 선언에서 0을 할당하여 선언된다.

 

순수 가상 함수 예시:

// An abstract class
class Test {
     // Data members of class
public:
     // Pure Virtual Function
     virtual void show() = 0;

     /* Other members */
};

 

완전한 예시:

(*추상 클래스에서 파생된 클래스는 순수 가상 함수를 구현한다.)

// C++ Program to illustrate the abstract class and virtual
// functions
#include <iostream>
using namespace std;

class Base {
     // private member variable
     int x;

public:
     // pure virtual function
     virtual void fun() = 0;

     // getter function to access x
     int getX() { return x; }
};

// This class inherits from Base and implements fun()
class Derived : public Base {
     // private member variable
     int y;

public:
     // implementation of the pure virtual function
     void fun() { cout << "fun() called"; }
};

int main(void)
{
     // creating an object of Derived class
     Derived d;

     // calling the fun() function of Derived class
     d.fun();

     return 0;
}

 

출력:

fun() called

2. 몇 가지 특징

① 클래스에 하나 이상의 순수 가상 함수가 있으면 그 클래스는 추상적인 클래스가 된다.

 

예시:

// C++ program to illustrate the abstract class with pure
// virtual functions
#include <iostream>
using namespace std;

class Test {
     // private member variable
     int x;

public:
     // pure virtual function
     virtual void show() = 0;

     // getter function to access x
     int getX() { return x; }
};

int main(void)
{
     // Error: Cannot instantiate an abstract class
     Test t;

     return 0;
}

 

출력:

Compiler Error: cannot declare variable 't' to be of abstract
type 'Test' because the following virtual functions are pure 
within 'Test': note:     virtual void Test::show() 

 

여기서 Test는 순수 가상 함수 Show()를 가지므로 추상 클래스이다.

 

② 우리는 추상 클래스 유형의 포인터와 참조를 가질 수 있다.

위와 달리 아래의 프로그램은 정상적으로 작동한다:

// C++ program that demonstrate that
// we can have pointers and references
// of abstract class type.

#include <iostream>
using namespace std;

class Base {
public:
     // pure virtual function
     virtual void show() = 0;
};

class Derived : public Base {
public:
     // implementation of the pure virtual function
     void show() { cout << "In Derived \n"; }
};

int main(void)
{
     // creating a pointer of type
     // Base pointing to an object
     // of type Derived
     Base* bp = new Derived();

     // calling the show() function using the
     // pointer
     bp->show();

     return 0;
}

 

출력:

In Derived 

 

③ 파생 클래스에서 순수 가상 함수를 재정의하지 않으면, 파생 클래스도 추상 클래스가 된다.

다음 예는 동일한 예를 보여준다:

// C++ program to demonstrate that if we do not override
// the pure virtual function in the derived class, then
// the derived class also becomes an abstract class

#include <iostream>
using namespace std;

class Base {
public:
     // pure virtual function
     virtual void show() = 0;
};

class Derived : public Base {
};

int main(void)
{
     // creating an object of Derived class
     Derived d;

     return 0;
}

 

출력:

Compiler Error: cannot declare variable 'd' to be of abstract type 
'Derived'  because the following virtual functions are pure within
'Derived': virtual void Base::show() 

 

④ 추상 클래스에는 생성자가 있을 수 있다.

예를 들어, 다음 프로그램은 위 예시와 달리 컴파일되고 잘 실행된다:

// C++ program to demonstrate that
// an abstract class can have constructors.

#include <iostream>
using namespace std;

// An abstract class with constructor
class Base {
protected:
     // protected member variable
     int x;

public:
     // pure virtual function
     virtual void fun() = 0;

     // constructor of Base class
     Base(int i)
     {
          x = i;
          cout << "Constructor of base called\n";
     }
};

class Derived : public Base {
     // private member variable
     int y;

public:
     // calling the constructor of Base class
     Derived(int i, int j)
          : Base(i)
     {
          y = j;
     }

     // implementation of pure virtual function
     void fun()
     {
          cout << "x = " << x << ", y = " << y << '\n';
     }
};

int main(void)
{
     // creating an object of Derived class
     Derived d(4, 5);

     // calling the fun() function of Derived class
     d.fun();

     // creating an object of Derived class using
     // a pointer of the Base class
     Base* ptr = new Derived(6, 7);

     // calling the fun() function using the
     // pointer
     ptr->fun();

     return 0;
}

 

출력:

Constructor of base called
x = 4, y = 5
Constructor of base called
x = 6, y = 7

 

⑤ C++의 추상 클래스는 struct 키워드를 사용하여 정의할 수도 있다.

 

예시:

struct shapeClass
{
     virtual void Draw()=0;
}

 

728x90