13.13 Copy initialization
https://www.learncpp.com/cpp-tutorial/copy-initialization/
copy初期化は次のスタイルです.
このセクションではclassのcopy初期化について説明します
この形式のcopy初期化評価は以下の通りである.
elisionが発生するため、copyコンストラクション関数なしでコンストラクション関数を実行
しかしelidingはc++17までは保障されていないのでcopy初期化は避けたほうがよい.
パラメータを渡したり返したりするときにcopyを使用して初期化します
Copy constructor called
Copy constructor called
-5/3
最初のcopyコンストラクション関数はmakenegative関数でパラメータを渡すときに発生します.
次に、関数内で返される過程で発生します.
ただし、パラメータとreturn valueが特定の条件を満たす場合、コンパイラは
省略する
copy初期化は次のスタイルです.
int x = 5;
intタイプの場合は上記と同様に簡単ですが、クラスの場合はもっと複雑です.このセクションではclassのcopy初期化について説明します
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初期化評価は以下の通りである.
Fraction six(Fraction(6));
前述したように、前回習ったanonymousobjectなので.elisionが発生するため、copyコンストラクション関数なしでコンストラクション関数を実行
しかしelidingはc++17までは保障されていないのでcopy初期化は避けたほうがよい.
Other places copy initialization is used
パラメータを渡したり返したりするときにcopyを使用して初期化します
#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コンストラクション関数はmakenegative関数でパラメータを渡すときに発生します.
次に、関数内で返される過程で発生します.
ただし、パラメータとreturn valueが特定の条件を満たす場合、コンパイラは
省略する
Reference
この問題について(13.13 Copy initialization), 我々は、より多くの情報をここで見つけました https://velog.io/@ikmy0ung/13.13-Copy-initializationテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol