: ํด๋์ค ๋ฉค๋ฒ ๋ฐ์ดํฐ๊ฐ ํฌ์ธํฐ๊ฐ ์๋ ์ํ์์ ,
๋ํดํธ ๋ณต์ฌ ์์ฑ์๊ฐ ํธ์ถ๋๋ฉด, ๋ ๊ฐ์ฒด์ ํฌ์ธํฐ๊ฐ
ํ๋์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๋ฉด์ ๋ฐ์ํ๋ ๋ฌธ์
: ์์ ๋ณต์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ผ๋ก
- ๊น์ ๋ณต์ฌ
- ์ฐธ์กฐ ์นด์ดํ ์ด ์์.
: ๊ฐ์ฒด์ ๋ชจ๋ ๋ฉค๋ฒ๋ฅผ ๋์
์ฐ์ฐ์๋ก ์ฒ๋ฆฌํจ.
-> ์์ ๋ณต์ฌ ๋ฌธ์ ๊ฐ ๋ฐ์!
: char * name, int age ๋ฅผ ๋ฉค๋ฒ๋ก ๊ฐ์ง๊ณ ์๋
Cat ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ผ. name์ strcpy๋ฅผ ์ฌ์ฉ
int main()
{
Cat a("bom", 1);
Cat b = a;
//Cat c(a);
}
- ์์ ๋ณต์ฌ๋ก ์ธํ ๋ฌธ์ ๋ฐ์ ์ฝ๋
-> ์๋ํ๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ๋ํดํธ ๋ณต์ฌ ์์ฑ์๋ฅผ ํตํด ํฌ์ธํฐ name์ ์ฃผ์๋ฅผ
2๊ฐ์ ๊ฐ์ฒด๊ฐ ๊ณต์ ํ๊ธฐ ๋๋ฌธ์.
1๋ฒ. ๊น์ ๋ณต์ฌ๋ก ์ฒ๋ฆฌํ๊ธฐ
: ๋ณต์ฌ ์์ฑ์์์ ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๊ณ , ๊ฐ์ ๋์
ํ๋ ๊ฒ์ด๋ค.
2๋ฒ. ์ฐธ์กฐ ์นด์ดํ
์ ํ์ฉํ์.
: ๋์ผํ ํฌ์ธํฐ์ ๋ํด ๋ช๋ฒ์ ์ฐธ์กฐํ๊ณ ์๋์ง๋ฅผ ์นด์ดํ
ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
c++์ shared_ptr์์ ์ฌ์ฉํจ.
// cppTest.cpp : ์ด ํ์ผ์๋ 'main' ํจ์๊ฐ ํฌํจ๋ฉ๋๋ค. ๊ฑฐ๊ธฐ์ ํ๋ก๊ทธ๋จ ์คํ์ด ์์๋๊ณ ์ข
๋ฃ๋ฉ๋๋ค.
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Cat
{
private :
char* name;
int age;
int* refCnt;
public :
Cat(const char* _name, int _age)
: age(_age)
{
refCnt = new int(1);
name = new char[strlen(_name) + 1];
strcpy(name, _name);
cout << "refCnt ์์ฑ " << endl;
}
~Cat()
{
{
--(*refCnt);
cout << "์นด์ดํ
1 ๊ฐ์" << endl;
}
if (*refCnt == 0)
{
delete[] name;
delete refCnt;
cout << "๋ฉ๋ชจ๋ฆฌ ํด์ " << endl;
}
}
Cat(const Cat& _cat)
: age(_cat.age), name{_cat.name}
{
++(*_cat.refCnt);
refCnt = _cat.refCnt;
cout << "์นด์ดํ
1 ์ฆ๊ฐ" << endl;
cout << "refCnt์ ์ฃผ์๋? " << &(refCnt) << endl;
cout << "refCnt์ ์ฃผ์๋? " << &(_cat.refCnt) << endl;
//name = new char[strlen(_cat.name) + 1];
//strcpy(name, _cat.name);
}
void print() const
{
cout << name << endl;
}
};
int main()
{
Cat a("bom", 1);
Cat b = a;
b.print();
a.print();
}
1) const char* , int ํ์
์ ๋ฉค๋ฒ๋ฅผ ๊ฐ์ง๊ณ , ๊ณ ์์ด์ ์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์
๋ ฅํ์.
2) ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ foo ํจ์๋ฅผ ๋ง๋ค์.
3) main์์ Car c(foo);
4) c.print ํด์ ์ด๋ฆ์ ์ถ๋ ฅํ์.
5) ์ถ๊ฐ์ ์ผ๋ก ์ด๋์์ฑ์ ํธ์ถ๋์์ ๋์ this ํฌ์ธํฐ์ ์ฃผ์๋ ํ์ธํด๋ณด์.
์ด๋ ์์ฑ์์ ๋ชจ์์ Cat(&&) ์ด๊ณ , ๋ณต์ฌ ์์ฑ์์ฒ๋ผ ๋ฉค๋ฒ๊ฐ ๋์ ์ ํ๊ณ ,
ํฌ์ธํฐ๊ฐ ์์ ๊ฒฝ์ฐ, ์๋ณธ ๊ฐ์ฒด ๋ฉค๋ฒ๋ฅผ = nullptr ์ฒ๋ฆฌํด์ ์ฐธ์กฐ๊ฐ์ ๋ ๋ฆฌ์.
int main()
{
Cat a = foo();
a.print();
std::cout << &a << std::endl;
}
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <limits.h>
#include <algorithm>
#include <map>
class Cat
{
private:
char* name;
int age;
public:
Cat(const char* _name, int _age)
: age{ age }
{
std::cout << "constru" << std::endl;
name = new char[strlen(_name) + 1];
strcpy(name, _name);
std::cout << this << std::endl;
}
Cat(const Cat& _copy)
{
std::cout << "copy constru" << std::endl;
name = new char[strlen(_copy.name) + 1];
strcpy(name, _copy.name);
std::cout << this << std::endl;
}
~Cat()
{
if (name != 0)
{
delete[] name;
std::cout << "delete name! " << std::endl;
}
std::cout << "destructor" << std::endl;
}
void print()
{
std::cout << name << std::endl;
}
//Cat(Cat&& movObj)
//{
// std::cout << "move Call" << std::endl;
// name = movObj.name;
// age = movObj.age;
// std::cout << this << std::endl;
// movObj.name = 0;
//}
};
Cat foo()
{
Cat c("naOng", 10);
std::cout << "foo" << std::endl;
std::cout << &c << std::endl;
return c;
}
int main()
{
Cat a = foo();
a.print();
std::cout << &a << std::endl;
}
foo ํจ์ ํธ์ถ๋ก ์ธํด c๊ฐ์ฒด๊ฐ ๋ง๋ค์ด์ง๊ณ , name ํฌ์ธํฐ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ ๋น๋จ.
์ด์ด์ ๋ฐํ์ ํ๋ฉด์ a๊ฐ์ฒด์๋ค๊ฐ ๋์
๋๋๋ฐ, ์ฌ๊ธฐ์ foo ์์ ํ ๋น๋ c๊ฐ์ฒด๋ ํ๊ดด๋จ. foo ํจ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์์๊ฐ์ฒด๊ฐ ์์ฑ๋๋ฉด์ ๋ณต์ฌ ์์ฑ์์ ์ธ์์ ์ ๋ฌํจ.
์ฌ๊ธฐ์ ์ค์ํ ๋ถ๋ถ์ด ๋ณต์ฌ ์์ฑ์๋ฅผ ์ง์
ํ๋ฉด์ 2๋ฒ์งธ name ํฌ์ธํฐ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ ๋น๋จ.
๋ณต์ฌ ์์ฑ์๋ก ์ธํด์ name ์์์ด 2๋ฒ์ด๋ ํ ๋น๋๋๋ฐ, foo ํจ์์์ ๋ฐํํ๊ณ ๋ฐ๋ก ์ฌ๋ผ์ง๋ ๊ฐ์ฒด c์ name ์์์ ์ ์ฌ์ฉํ๋ฉด ์ข์ง ์์๊น? ๋ ์๊ฐ์ ํด์ผ ํ๋ค!
์ด๋์์ฑ์๋?
์ด๋ฌํ ๋ถ๋ถ์ ๊ฐ์ ํ๊ธฐ ์ํด c++11์์ ๋์
๋ ๊ฒ์ด ์ด๋์์ฑ์์ด๋ค.
์ด๋ ์์ฑ์๋ ์์์ ๋ณต์ฌํ๋ ๊ฒ์ด ์๋๋ผ. ์ด๋ํ๋ ๊ฒ์.
์์ ๋ณต์ฌ์ฒ๋ผ ํฌ์ธํฐ ์ฃผ์๋ง ๋๊ฒจ์ฃผ๊ณ , ์๋ณธ ๋ฐ์ดํฐ์์๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํฌ๊ธฐํ๋ฉด ๋จ.
๊ณ ์ฐฐ:
์ฐจ๋ผ๋ฆฌ foo ํจ์์์ ๊ฐ์ฒด c๊ฐ ํ ๋น๋ name ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ์ฒด a์ name์๋ค๊ฐ ์์ ์ด๋ํ๋ฉด
๋ณต์ฌ ์์ฑ์์์ 2๋ฒ์งธ๋ก name ํฌ์ธํฐ๊ฐ ํ ๋น๋๋ ์์์ ์๋ ์ ์์.
์ฌ๊ธฐ์ ์์์ผ ๋๋ ๋ถ๋ถ์ด ์ด๋์์ฑ์๋ ๋ณต์ฌ ์์ฑ์๋ ์ด์จ๋ ํธ์ถํ๋ฉด
๊ฐ์ฒด๋ ์์ฑ๋๋ค๋ ๊ฒ์ด๋ค. name ์์์ด 2๋ฒ ํ ๋น๋๋ ๊ฒ์ 1๋ฒ๋ง ํ ๋นํ์๋ ๊ฒ์ด ์ด๋์์ฑ์์ ๋ชฉ์ ์ด๋ค.
#include <iostream>
#include <vector>
//using namespace std;
//#include <stdio.h>
#include <winsock2.h>
#include <thread>
#pragma comment(lib, "ws2_32")
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Windows.h>
#include <memory>
using namespace std;
#include <vector>
#include <algorithm>
class Cat
{
private :
char* name;
int age;
public:
Cat(const char* _name, int _age)
: age{age}
{
std::cout << "constru" << std::endl;
name = new char[strlen(_name) + 1];
strcpy(name, _name);
std::cout << this << std::endl;
}
Cat(const Cat& _copy)
{
std::cout << "copy constru" << std::endl;
name = new char[strlen(_copy.name) + 1];
strcpy(name, _copy.name);
std::cout << this << std::endl;
}
~Cat()
{
if (name != 0)
{
delete[] name;
std::cout << "delete name! " << std::endl;
}
std::cout << "destructor" << std::endl;
}
void print()
{
std::cout << name << std::endl;
}
Cat(Cat&& movObj)
{
std::cout << "move Call" << std::endl;
name = movObj.name;
age = movObj.age;
std::cout << this << std::endl;
movObj.name = 0;
}
};
Cat foo()
{
Cat c("naOng", 10);
std::cout << "foo" << std::endl;
std::cout << &c << std::endl;
return c;
}
int main()
{
Cat a = foo();
a.print();
std::cout << &a << std::endl;
}
// ์์ ํ๋ก์ ํธ๋ ์ฝ๋ ์ต์ ํ๊ฐ ์๋์ด ์๋ ๊ฒฝ์ฐ์ด๋ค. 240803
- ์ผ๋จ ์ ์ด๋์์ฑ์๊ฐ ํธ์ถ๋์๋๋ฉด? ์์๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ณ ์๊ธฐ
๋๋ฌธ์ด๋ผ๋ ๊ฒ์ ํ์ ํด์ผ ํ๋ค!
๊ฒฐ๋ก
-> foo์์ ๋ฐํ๋๋ ๊ฐ์ฒด c๊ฐ ๊ฐํ์ ์ผ๋ก ๋ฐํ๋จ.
์ปดํ์ผ๋ฌ๋ ์ง์ญ ๊ฐ์ฒด์ธ c๊ฐ fooํจ์์์ ์ ๊ฑฐ๋๋ฏ๋ก, ๋ณต์ฌ์์ฑ์๋ฅผ ์์์ ์ผ๋ก ํธ์ถํจ.
: foo() ํจ์์ ๊ฒฝ์ฐ, "hello" ๊ฐ ํธ์ถ๋๊ธฐ๋ ์ ์ ์์๊ฐ์ฒด๊ฐ
์๋ฉธ๋จ.
๋ฉ๋ชจ๋ฆฌ๊ฐ ์์ฑ,ํด์ ๊ฐ ๋ฐ์ํ๋ค๋ ๊ฒ์.
์ฐจ๋ผ๋ฆฌ foo์์ ๋ฐํ๋๋ ์์๊ฐ์ฒด์ ์์์ ๊ทธ๋๋ก ๊ฐ์ฒด cc๊ฐ ๋ฐ๋๋ค๋ฉด,
๋ฉ๋ชจ๋ฆฌ ๊ด์ ์์ ์ฑ๋ฅ์ ๊ฐ์ง๊ณ ์ฌ ์ ์์.
: ์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด, move ์ฒ๋ฆฌ๋์ง ์๊ณ , ์ต์ ํ๋์ด์ ๋ฐ๋ก ์์ฑ์ ํ๋๋ง ํธ์ถ๋๋ค.
: ์ด๋์์ ์๋ ๊ฐ์ฒด ๋ด์ ๋ฉค๋ฒ ์์์ ์ด๋์ํค๋ ๊ฒ์ด์ง, ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ
ํต์งธ๋ก ์ฎ๊ธฐ๋ ๊ฒ์ ์๋/
(์ด๋์์ฑ์ ์์ฑํ์ง ์์์ ๋) ์์์ ์์๊ฐ์ฒด๊ฐ call ๋๋ฉด์ ๋ณต์ฌ ์์ฑ์๋ฅผ ํธ์ถํ๋ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์์.
์์๊ฐ์ฒด๋ Rvalue์ด๋ฏ๋ก, const& Obj ํ์ ๋ณด๋ค ์ฐ์ ์์๊ฐ ๋์ Obj&& ์ธ์๋ก
๋์ด ์๋ ์ด๋์์ฑ์๋ฅผ ํธ์ถํ๊ฒ ํ์.
- ์ถ๊ฐ์ ์ผ๋ก ์์์ ๊ทธ๋๋ก ์ด๋ํ๊ณ , ์๋ณธ ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํ๋ ์์ ์ ํด์ผํจ.
- 1) ๋ฉค๋ฒ ์์์ ๊ทธ๋ฅ ๋ณต์ฌ ๋์ ํ ํ,
- 2) ์ธ์๋ก ๋ฐ์ ๊ฒ์ค์์ ํฌ์ธํฐ๊ฐ ์๋ค๋ฉด, ํฌ์ธํฐ๋ฅผ 0์ผ๋ก ์ค์
์์์ฝ๋์ ์ค๋ช
๋๋ก ํ๊ธฐ ์ํ ๊ฐ๋
: c++์์ ์ฐธ์กฐ๋๋ ํฌ์ธํฐ๊ฐ 0์ด๋ผ๋ฉด, ๋ฉค๋ฒ ๋ฐ์ดํฐ์ ํด์ ๋
๋ฐ์ํ์ง ์์. ๋ฑํ ์กฐ๊ฑด ์ฒ๋ฆฌ์ํด๋ ๋จ.
๊ทธ๋ฆผ
์ด ์ํฉ์์ ์์๊ฐ์ฒด์ชฝ์ ์ฐธ์กฐ๋ฅผ 0์ผ๋ก ํ์.
๋ณต์ฌ ์์ฑ์์ ์ธ์์ฒ๋ผ ์ฌ์ฉํ๊ธฐ์๋ lvalue๋ก ๋ณด๋์ ๋๋
์๋ฉธ๋์ง ์๊ณ , ๊ณ์ํด์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ฏ๋ก!
->์ฆ, rvalue์ ํํด์๋ง ์ฒ๋ฆฌ๋ฅผ ํด์ผ ํ๋ฏ๋ก
(Point &&p) ํํ๋ก ์ธ์๋ฅผ ์ค์ ํด์ผ ํจ.
-> ๋ฐ๋ผ์ ๋ณต์ฌ ์์ฑ์์ ์ด๋ ์์ฑ์ 2๊ฐ๋ฅผ ๋ง๋ค์ด์ผ ํจ.
--> ์ด๋์์ฑ์๋ฅผ ๋ง๋ค์ง ์์ผ๋ฉด, ์์๊ฐ์ฒด๋ฅผ ๋ณต์ฌ์์ฑ์๊ฐ ์ฌ์ฉํ๊ฒ ๋๋ค.
: rvalue๋ฅผ ์ธ์๋ก ๋ฐ์์ ์๋ณธ ๊ฐ์ฒด์
์์ ๊ถ, ์์์ ์ด์ ํ๊ฒ ํ๋ ์์ฑ์๋ฅผ ๋งํจ.
ํฌ์ธํฐ์ ๊ฒฝ์ฐ๋ ์ฃผ์๋ฅผ ๋๊ธฐ๊ณ , ์๋ณธ ๊ฐ์ฒด๊ฐ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ๋ฅผ nullptr ์ฒ๋ฆฌํด์ผ ํจ.
: ๊ฐ์ฒด์ ์์ ๊ถ์ ์ด์ ํ๊ณ ์ถ์ ๋ ์ฌ์ฉํจ.
์ด๋ ์ํ ํ, ๋ฐ๋์ ํด์ผํ ๋์.
: ์๋ณธ์ ํฌ์ธํฐ๋ ๋ฐ๋์ 0๊ฐ์ผ๋ก ๋ง๋ค์ด์ผ ํจ!
-> 0์ผ๋ก ํ๋ฉด ์๋ฉธ์์์ delete ํ๋ ์ฝ๋๊ฐ ์๋๋ผ๋ ์๋ฌด์ผ ์์ด ์ง๋๊ฐ๋ค.
: ๊ทธ๋ฆผ 1๋ฒ์ ํ์ดํ ํํ, ์ด๋์ฒ๋ฆฌํด์ ์์ name ์ด
๋ค์ ํ๋ฒ ๋์ ํ ๋น๋๋ ๊ฒ์ ์ฐจ๋จํ์.
**- ๊ทธ๋ฆผ 2๋ฒ : ์ด๋ ์์ฑ์๋ฅผ ๋ง๋ค ๊ฒฝ์ฐ.
๋ฐ๋์ ์๋ณธ ํฌ์ธํฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ 0์ผ๋ก ๋ง๋ค์ด์ผ ํจ!
๋ณต์ฌ ์์ฑ์๋ cont &point ํํ์ด๊ธฐ ๋๋ฌธ์
lvalue, rvalue 2๊ฐ ๋ชจ๋ ๋ฐ์ ์ ์์.
์ด๋์์ฑ์๋ point&& ์ด๊ธฐ ๋๋ฌธ์ rvalue๋ง ๋ฐ์ ์ ์์.
: rValue๋ฅผ ์ธ์๋ก ๋ณด๋ผ๋ ํธ์ถ๋๋ ์ฐ์ ์์.
์ด๋ ์์ฑ์ > ๋ณต์ฌ ์์ฑ์.
// move ์์ฑ์๋ฅผ ์ฃผ์ ์ฒ๋ฆฌํ์.
int main()
{
point p;
point p2 = p;
point p3 = point();
}
int main()
{
point p = foo();
}