C++의 순수 가상 함수 및 추상 클래스

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

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

순수 가상 함수의 예

C++




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

완전한 예

순수 가상 함수는 Abstract 클래스에서 파생된 클래스에 의해 구현됩니다.

C++




// C++ Program to illustrate the abstract class and virtual> // functions> #include> 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 

몇 가지 흥미로운 사실

1. 순수 가상 함수가 하나 이상 있으면 클래스는 추상 클래스입니다.

아래 C++ 코드에서 Test는 순수 가상 함수 show()를 갖고 있기 때문에 추상 클래스입니다.

C++




// C++ program to illustrate the abstract class with pure> // virtual functions> #include> 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() 

2. 추상 클래스 유형의 포인터와 참조를 가질 수 있습니다.

예를 들어, 다음 프로그램은 제대로 작동합니다.

C++




// C++ program that demonstrate that> // we can have pointers and references> // of abstract class type.> #include> 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 '> ; }> };> 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->쇼();> > return> 0;> }>

산출

In Derived 

3. 파생 클래스의 순수 가상 함수를 재정의하지 않으면 파생 클래스도 추상 클래스가 됩니다.

다음 예제에서는 동일한 내용을 보여줍니다.

C++




// 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> 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() 

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

예를 들어, 다음 프로그램은 정상적으로 컴파일되고 실행됩니다.

C++




// C++ program to demonstrate that> // an abstract class can have constructors.> #include> 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 '> ;> > }> };> 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 < <> ' '> ;> > }> };> 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->재미();> > return> 0;> }>

산출

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

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

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

자바와의 비교

Java에서는 abstract 키워드를 사용하여 클래스를 추상화할 수 있습니다. 마찬가지로, abstract 키워드를 사용하여 함수를 순수 가상 또는 추상으로 만들 수 있습니다. 보다 Java의 추상 클래스 상세 사항은.

인터페이스와 추상 클래스

인터페이스에는 해당 메서드의 구현이 없으며 메서드 선언의 컬렉션으로 간주될 수 있습니다. C++에서는 모든 메서드를 순수 가상으로 만들어 인터페이스를 시뮬레이션할 수 있습니다. Java에는 인터페이스에 대한 별도의 키워드가 있습니다.

인터페이스를 C++의 헤더 파일로 생각할 수 있습니다. 헤더 파일에서처럼 인터페이스를 구현할 클래스의 본문만 제공합니다. 마찬가지로 Java in Interface에서는 클래스의 본문만 제공하고 이를 구현하는 클래스에 실제 코드를 작성합니다.