13.16 Shallow vs. deep copying
https://www.learncpp.com/cpp-tutorial/shallow-vs-deep-copying/
C++は私たちのクラスを知らないからです.
default copy constructorとdefault付与オペレータ
memberwise copy(shallow copyとも呼ばれる)を行う
これは、c++がすべてのメンバーをコピーしてインポートすることを意味します.
クラスが簡単であれば、これは大きな問題ではありません.
ただし、メモリを動的に割り当てるクラスであれば、物語は異なります.
pointerの共有に伴い、思わぬ動作が発生する可能性があります
また、最後にメモリを解放すると、解放されたメモリが解放されるため、クラッシュが発生します.
この場合、答えはdeepcopyです
deepcopyは、copyにメモリを割り当て、実際の値のみをコピーします.
Now let’s do the overloaded assignment operator. The overloaded assignment operator is slightly trickier: We added a self-assignment check. We return *this so we can chain the assignment operator. We need to explicitly deallocate any value that the string is already holding (so we don’t have a memory leak when m_data is reallocated later).
実際、stringをcharpointerで直接処理するよりも、
std::stringを使用すると、問題を簡単に解決できます.
std::string、vectorはメモリ管理をサポートします.
メモリを直接管理しないで、既存のライブラリを使用したほうがいいです.
Shallow copying
C++は私たちのクラスを知らないからです.
default copy constructorとdefault付与オペレータ
memberwise copy(shallow copyとも呼ばれる)を行う
これは、c++がすべてのメンバーをコピーしてインポートすることを意味します.
クラスが簡単であれば、これは大きな問題ではありません.
ただし、メモリを動的に割り当てるクラスであれば、物語は異なります.
#include <cstring> // for strlen()
#include <cassert> // for assert()
class MyString
{
private:
char* m_data{};
int m_length{};
public:
MyString(const char* source = "" )
{
assert(source); // make sure source isn't a null string
// Find the length of the string
// Plus one character for a terminator
m_length = std::strlen(source) + 1;
// Allocate a buffer equal to this length
m_data = new char[m_length];
// Copy the parameter string into our internal buffer
for (int i{ 0 }; i < m_length; ++i)
m_data[i] = source[i];
}
~MyString() // destructor
{
// We need to deallocate our string
delete[] m_data;
}
char* getString() { return m_data; }
int getLength() { return m_length; }
};
上記のダイナミックメモリの処理に浅いコピーを使用する場合pointerの共有に伴い、思わぬ動作が発生する可能性があります
また、最後にメモリを解放すると、解放されたメモリが解放されるため、クラッシュが発生します.
Deep copying
この場合、答えはdeepcopyです
deepcopyは、copyにメモリを割り当て、実際の値のみをコピーします.
// assumes m_data is initialized
void MyString::deepCopy(const MyString& source)
{
// first we need to deallocate any value that this string is holding!
delete[] m_data;
// because m_length is not a pointer, we can shallow copy it
m_length = source.m_length;
// m_data is a pointer, so we need to deep copy it if it is non-null
if (source.m_data)
{
// allocate memory for our copy
m_data = new char[m_length];
// do the copy
for (int i{ 0 }; i < m_length; ++i)
m_data[i] = source.m_data[i];
}
else
m_data = nullptr;
}
// Copy constructor
MyString::MyString(const MyString& source)
{
deepCopy(source);
}
As you can see, this is quite a bit more involved than a simple shallow copy! First, we have to check to make sure source even has a string (line 11). If it does, then we allocate enough memory to hold a copy of that string (line 14). Finally, we have to manually copy the string (lines 17 and 18).Now let’s do the overloaded assignment operator. The overloaded assignment operator is slightly trickier:
// Assignment operator
MyString& MyString::operator=(const MyString& source)
{
// check for self-assignment
if (this != &source)
{
// now do the deep copy
deepCopy(source);
}
return *this;
}
付与オペレータはcopyコンストラクション関数とよく似ていますが、3つの主な違いがあります.A better solution
実際、stringをcharpointerで直接処理するよりも、
std::stringを使用すると、問題を簡単に解決できます.
std::string、vectorはメモリ管理をサポートします.
メモリを直接管理しないで、既存のライブラリを使用したほうがいいです.
Reference
この問題について(13.16 Shallow vs. deep copying), 我々は、より多くの情報をここで見つけました https://velog.io/@ikmy0ung/13.16-Shallow-vs.-deep-copyingテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol