13.13 Copy initialization

주홍영·2022년 3월 18일
0

Learncpp.com

목록 보기
156/199

https://www.learncpp.com/cpp-tutorial/copy-initialization/

copy initialization은 아래와 같은 스타일이다

int x = 5;

int 타입의 경우 위처럼 간단하지만 class의 경우 좀 더 복잡하다
이번 섹션에서는 class의 copy initialization에 대해서 다룬다

Copy initialization for classes

#include <cassert>
#include <iostream>

class Fraction
{
private:
    int m_numerator;
    int m_denominator;

public:
    // Default constructor
    Fraction(int numerator=0, int denominator=1)
        : m_numerator(numerator), m_denominator(denominator)
    {
        assert(denominator != 0);
    }

    friend std::ostream& operator<<(std::ostream& out, const Fraction& f1);
};

std::ostream& operator<<(std::ostream& out, const Fraction& f1)
{
	out << f1.m_numerator << "/" << f1.m_denominator;
	return out;
}

int main()
{
    Fraction six = Fraction(6);
    std::cout << six;
    return 0;
}

위의 코드를 실행시키면 의도한대로 실행된다

이런 형태의 copy initialization은 다음과 같이 evaluate된다

Fraction six(Fraction(6));

위처럼 된 경우 저번에 배운 레슨에 의해 anonymous object 이기 때문에
elision이 발생해서 copy constructor 없이 constructor가 실행된다
다만 eliding은 c++17 이전에서는 보장되지 않으므로 copy initialization은 피하는 것이 좋다

Other places copy initialization is used

우리가 argument를 pass하거나 return으로 돌려줄 때도 copy initialization이 사용된다

#include <cassert>
#include <iostream>

class Fraction
{
private:
	int m_numerator;
	int m_denominator;

public:
    // Default constructor
    Fraction(int numerator=0, int denominator=1)
        : m_numerator(numerator), m_denominator(denominator)
    {
        assert(denominator != 0);
    }

        // Copy constructor
	Fraction(const Fraction& copy) :
		m_numerator(copy.m_numerator), m_denominator(copy.m_denominator)
	{
		// no need to check for a denominator of 0 here since copy must already be a valid Fraction
		std::cout << "Copy constructor called\n"; // just to prove it works
	}

	friend std::ostream& operator<<(std::ostream& out, const Fraction& f1);
        int getNumerator() { return m_numerator; }
        void setNumerator(int numerator) { m_numerator = numerator; }
};

std::ostream& operator<<(std::ostream& out, const Fraction& f1)
{
	out << f1.m_numerator << "/" << f1.m_denominator;
	return out;
}

Fraction makeNegative(Fraction f) // ideally we should do this by const reference
{
    f.setNumerator(-f.getNumerator());
    return f;
}

int main()
{
    Fraction fiveThirds(5, 3);
    std::cout << makeNegative(fiveThirds);

    return 0;
}

위의 프로그램을 실행시키면 다음과 같은 결과가 출력된다

Copy constructor called
Copy constructor called
-5/3

첫번째 copy constructor는 makeNegative함수에서 argument를 전달하면서 발생하고
다음은 함수 내에서 return하는 과정에서 발생한다

하지만 argument와 return value가 특정 기준을 만족하면 컴파일러는 copy constructor를
생략하기도 한다

profile
청룡동거주민

0개의 댓글

관련 채용 정보