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 된다
댓글 없음:
댓글 쓰기