Explicit 생성자
explicit a. 명백한, 뚜렷한(clear), 명시적인
- 직접 초기화 (direct initialization) : OFile fi("a.txt");와 같이 '=' 없이 초기화 하는 것
- 복사 초기화 (copy initialization) : OFile f2 = "a.txt"; 와 같이 '=' 사용해서 초기화 하는 것
함수 인자 전달시 복사 초기화를 사용한다.
foo("hello")를 보낸다는 것은 hello 이름으로 File이 error 없이 생성이 된다.
특정 클래스 설계시 복사 초기화를 사용하지 못하게 하는 것이 좋을 때가 있다.
#include <iostream>
class OFile
{
FILE* file;
public:
OFile(const char* filename)
{
file = fopen(filename, "wt");
}
~OFile() { fclose(file); }
};
void foo( OFile f) {} // OFile f = "hello";
int main()
{
OFile f1("a.txt"); // OK 직접 초기화
OFile f2 = "a.txt"; // OK
foo("hello"); // OK 문제 없이 수행된다.
}
explicit를 사용한 생성자는 복사 초기화를 사용할 수 없다.
OFile f2 = "a.txt"; // error
foo("hello"); // error
이 경우 복사 생성자로 생성하기 때문에 에러가 발생한다.
#include <iostream>
class OFile
{
FILE* file;
public:
explicit OFile(const char* filename) // ******* explicit 생성자 *********
{
file = fopen(filename, "wt");
}
~OFile() { fclose(file); }
};
void foo( OFile f) {} // OFile f = "hello";
int main()
{
OFile f1("a.txt");
OFile f2 = "a.txt"; // error
foo( f1 );
foo("hello"); // error
}
main.cpp:19:16: error: conversion from ‘const char [6]’ to non-scalar type ‘OFile’ requested
main.cpp:22:16: error: could not convert ‘(const char*)"hello"’ from ‘const char*’ to ‘OFile’
explicit 생성자 확인 방법?
복사 생성자로 초기화 되는지를 확인해보고 문제가 없으면 explicit가 아님을 알 수 있다. 반대로 문제가 있으면 explicit 생성자 임을 알 수 있다.
#include <memory>
#include <vector>
#include <string>
#include <iostream>
int main()
{
std::string s1("hello"); // ok string은 explicit 생성자가 아니기에 둘 다 사용 가능
std::string s2 = "hello"; //ok
std::vector<int> v1(10); // ok
std::vector<int> v2 = 10; // error : vector는 생성자가 explicit 임을 알 수 있다.
std::vector<int> v3 = {10}; // ok : 호출 되는 생성자가 다르기에 에러가 나지 않는다.
// shared_ptr : C++ 표준 스마트 포인터
std::shared_ptr<int> p1( new int ); // ok
std::shared_ptr<int> p2 = new int; // error : 생성자가 explicit 임을 알 수 있다.
}
main.cpp:12:27: error: conversion from ‘int’ to non-scalar type ‘std::vector’ requested
main.cpp:18:31: error: conversion from ‘int*’ to non-scalar type ‘std::shared_ptr’ requested
'C++' 카테고리의 다른 글
[C++] static member (정적 멤버), static 변수, static 함수 (0) | 2021.08.22 |
---|---|
[C++] 복사 생성자 (copy constructor), 얕은 복사 (Shallow Copy), 깊은 복사 (deep copy) (0) | 2021.08.21 |
[C++] Class : 멤버 초기화 리스트 (member initializer lists) (0) | 2021.08.19 |
[C++] 생성자, 소멸자, 위임 생성자, default 생성자 (0) | 2021.08.19 |
[C++] 객체지향 : 접근지정자 private, public, friend (0) | 2021.08.18 |
댓글