728x90

클래스를 사용하면서 자주 보게 되는 키워드들에 대해서 알아보자. 

 

const

먼저 const는 constant의 줄임말로 상수 취급을 해준다는 말이다. 즉 값을 바꾸는 것을 방지한다고 보면 된다. const 키워드는 C++ 개발을 안전하게 해 준다. 가능하면 붙여줄 수 있는 곳에 다 붙여주는 것이 좋다. 아래 코드는 const의 사용 예제이다. 

#include <iostream>
#include <string>

class Dog
{
public:
    Dog(std::string) : mName{std::move(name)} {};
    void speak() const
    {
        std::cout << mName << std::endl;
    }
private:
    std::string mName;
    
}

int main()
{
    const Dog choco{"choco"};
    choco.speak();
}

Dog클래스의 멤버 함수인 speak() 함수를 보면 오른쪽에 const키워드가 있는 것을 확인할 수 있다. 이는 멤버 함수를 읽기 전용 함수로 만들어주는 키워드 이기 때문에 함수 내부에서 객체의 멤버 변수에 대해서 수정이 불가하다. 또한 main함수에서 객체 자체를 const객체로 선언을 하였기 때문에 객체의 멤버 변수에 대해서 재정의가 불가하다. 당연하게 만약 const로 선언이 된 객체에서 비 const멤버 함수를 호출하는 것은 불가하다. 쉽게 생각하면 애초에 객체부터 상수화 된 객체인데 멤버 함수에서 수정할 여지가 있다면 안되기 때문이다. 

 

하지만, const 멤버 함수에서 멤버 변수에 대한 수정이 가능한 경우가 있다. 바로 mutable키워드이다. 

만약 클래스의 멤버 변수가 mutable로 선언이 된 경우에는 const멤버 함수 내에서 수정이 가능하다.

#include <iostream>
#include <string>

class Dog
{
public:
    Dog(std::string) : mName{std::move(name)} {};
    void speak() const
    {
        mName = "cream";
        std::cout << mName << std::endl;
    }
private:
    mutable std::string mName;
}

int main()
{
    const Dog choco{"choco"};
    choco.speak();
    //cream
}

위와 같이 mutable로 선언된 string객체가 const멤버 함수 speak() 내에서 수정이 된 것을 확인할 수 있다. 하지만, 이렇게 사용 가능한 것임에도 불구하고 mutable키워드로 멤버 변수를 선언하는 것을 지양해야 한다. 왜냐하면 우리가 const키워드를 사용하는 이유는 멤버 변수의 수정을 막기 위함이다. const를 붙여줌으로써 컴파일러가 멤버 변수의 수정이 불가하다는 것을 인지하고 수정이 될 경우 오류가 있다고 알려주지만 mutable의 경우는 const로 선언한 것을 무시를 해주는 것이기 때문에 지양을 해야 한다. 

 

 

explicit

explicit키워드는 C++에서 implicit conversion을 막기 위함에 있다. expllicit키워드는 주로 constructor에서 사용이 된다.

#include <iostream>
#include <string>

class Cat
{
public:
	explicit Cat(int age) : mAge{ age } {};
	Cat(std::string name, int age) : mName{ std::move(name) }, mAge{ age } {};

private:
	int mAge;
	std::string mName;
	mutable std::string changable = "initial";			
};

int main()
{
    Cat choco = 3; //error
    Cat choco{3};
}

 Cat 클래스에서 interger variable을 1개 받는 Constructor를 보게 되면 explicit키워드가 있다. 이 의미는 main함수에서 명확하게 확인할 수 있다. 만약 객체에 integer값은 대입 연산자로 대입을 하게 될 경우 integer 상수 3이 implicit class-type consversion이 일어나게 된다. 이 뜻은 임시 객체에 3이라는 값을 저장하고 다시 임시 객체를 choco객체에 복사를 하괴 되는 과정이 일어난다. 이는 많은 메모리 손실을 야기하므로 explicit 하게 말 그대로 Argument를 명백하게 curly brace에 넣어서 넘겨줘라 라고 생각하면 쉽다. 

 

통상 클래스를 구성할때 Argument가 1개인 Constructor는 explicit키워드를 넣어주어 implicit conversion을 방지하는 것이 좋다. 

+ Recent posts