Post Lists

2018년 9월 2일 일요일

virtual function과 pure virtual function(=0)의 차이 + =delete, =default에 대한 설명

https://stackoverflow.com/questions/2652198/difference-between-a-virtual-function-and-a-pure-virtual-function

virtual function은 그것의 클래스를 polymorphic base class로 만든다. 파생된 클래스들은 virtual functions을 override할 수 있다. base class 포인터/레퍼런스를 통해 호출된 virtual functions들은 런타임에 resolved 될 것이다. 즉, 그 오브젝트의 dynamic type(동적 타입)이 그것의 static type을 대신해서 사용된다:


DerivedClass d;
BaseClass& rb = d;
// if Base::f() is virtual and Derived overrides it, Derived::f() will be called
rb.f();

pure virtual function은 선언문이 =0 으로 끝나는 virtual function이다:


class Base
{
   // . . .
   virtual void f() = 0;
   // . . .
}

pure virtual function은 implicitly하게 class가 abstract를 정의도도록 한다 (너가 명시적으로 class abstract를 선언할 수 있는 키워드를 가진 자바에서와 다르게). Abstract classes들은 인스턴스화 될 수 없다. 파생된 클래스들은 모든 상속된 pure virtual functions을 override/implement할 필요가 있다. 만약 그 파생된 클래스들이 그렇게 하지 않으면, 그것들 또한 추상화될 것이다.

C++의 한 가지 흥미로운 '특징'은 한 클래스가 한 구현을 가지는 pure virtual function을 정의할 수 있다는 것이다. (https://stackoverflow.com/questions/2609299/use-cases-of-pure-virtual-functions-with-body , 여기에서는 pure virtual function에 구현을 넣는 것은 잘못 설계한 것이라고 말한다).

C++11은 pure virtual functions의 syntax에 대해 유사하게 보이는 delte와 default 키워드에 대해 새로운 사용법을 가져왔었다:


my_class(my_class const &) = delete;
my_class& operator=(const my_class&) = default;

delete와 default에 대한 이 사용법에 더 정보가 필요하다면 이 질문과 이것을 보아라.

https://stackoverflow.com/questions/5513881/meaning-of-delete-after-function-declaration
delete에 대한 답.

C++ Programming Language [4th Edition] - Bjarne Stroustrup book의 이 발췌는 =delete를 사용하는 것 뒤에 있는 진짜 목적에 대해 말한다 .

위계까 있는 한 클래스를 default copy or move하는 것을 사용하는 것은 일반적으로 재앙이다: 한 base(class)에 대한 포인터만이 주어진다면, 우리는 간단히 그 파생된 클래스가 무엇을 가지고 있는지를 모른다, 그래서 우리는 그것들을 어떻게 복사할지를 모른다. 그래서, 하기에 가장 좋은 것은 보통 default copy and move operations를 delete하는 것이다. 즉, 그러한 두 연산의 기본 정의를 제거하는 것이다:


class Shape
{
public:
   Shape(const Shape&) =delete; // no copy operations
   Shape& operator=(const Shape&) =delete;

  Shape(Shape&&) = delete; // no move operations
  Shape& operator=(Shape&&) = delte;
  ~Shape();
  // . . .
}

이제 한 Shape를 복사하려는 시도는 컴파일러에 의해 잡힐 것이다. 그 =delete 메커니즘은 일반적이다. 즉, 그것은 어떤 연산을 제지하기 위해 사용되어질 수 있다.

https://stackoverflow.com/questions/13576055/how-is-default-different-from-for-default-constructor-and-destructor
default에 대한 답.


class B
{
public:
   B(){}
   int i; 
   int j;
};


class B
{
public:
   B() = default;
   int i; 
   int j;
};

둘 사이의 중요한 차이점은, B() = default; 으로 정의된 default constructor가 not-user defined라고 고려되는 것이다. 이것은

B* pb = new B(); // use of () triggers value-initialization value

constructor를 사용하지않는 특별한 종류의 초기화가 경우에 대체될 것이고, 내장 타입에 대해 이것은 zero-initialization의 결과를 만들어 낼 것이다. B() {}의 경우에, 이것은 발생하지 않을 것이다. C++ standard n3337은 다음과 같이 말한다.

type T인 한 오브젝트를 value-initialize를 하는 것은 의미한다:

- 만약 T가 user-provided constructor가 있는 (가급적 cv-qualified) class type이라면, 그러면 T에 대한 default constructor가 호출된다 (그리고, 만약 T가 어떠한 접근 간으한 default constructor를 가지고 있지 않다면 초기화는 잘못된 형식이다.)

- 만약 T가 user-provided constructor가 없는 (가급적, cv-qualified) union이 아닌 class type이라, 그러면 그 오브젝트는 zero-initialized 되고, 만약 T의 implicitly-declared default constructor가 non-trivial하다면, 그 constructor 호출된다.

- 만약 T가 array type이라면, 그러면 각 원소는 value-initialized된다; - 만약 그렇지 않다면 그 오브젝트 zero-initialized 된다

댓글 없음:

댓글 쓰기