본문 바로가기
  • 쓸쓸한 개발자의 공부방
C++

[C++] Explicit 생성자

by 심찬 2021. 8. 20.

 

 

 

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

 

 

 

댓글