๐ŸŽ„์ฝ”๋”ฉ ๊ทœ์น™ : move ํ•จ์ˆ˜

๋ณด๋ฌผ์ฐฝ๊ณ ยท2022๋…„ 9์›” 11์ผ
0

c++Intermediate ์ฝ”๋“œ๋ˆ„๋ฆฌ

๋ชฉ๋ก ๋ณด๊ธฐ
39/62
post-thumbnail

move ์˜ ์ •์˜

: lvalue๋ฅผ rvalue๋กœ ์บ์ŠคํŒ…ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ.

Object obj;
static_cast<object&&>(obj);
move(obj);
๋™์ผํ•œ ์˜๋ฏธ์ด๋‹ค.

problem

: ์ด์ „์— ๋งŒ๋“  cat ํด๋ž˜์Šค๋ฅผ ๊ทธ๋Œ€๋กœ ์ด์šฉํ•˜์ž.
1) Cat a("kitty", 10); ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ž.
2) Cat b ๊ฐ์ฒด์—๋‹ค๊ฐ€ a ๊ฐ์ฒด์ธ lvalue๋ฅผ rValue๋กœ ์บ์ŠคํŒ… ๋Œ€์ž…ํ•˜์ž.
3) a์™€ b์˜ name์„ ์ถœ๋ ฅํ•ด๋ณด์ž.
4) ์บ์ŠคํŒ… ํ•œ ๊ฒƒ์„ ๋‹ค๋ฅธ ํ‚ค์›Œ๋“œ๋กœ ๋ณ€๊ฒฝํ•ด๋ณด์ž.
5) Cat b("Tom" , 20); ์œผ๋กœ ๋ณ€๊ฒฝํ•œ ํ›„,
6) b = a ๋Œ€์ž…ํ•ด๋ณด์ž.
7) ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ๋„ ์žˆ๋Š”๋ฐ, ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ผ.
8) move ๋Œ€์ž…ํ•ด๋ณด์ž.

๋‚˜์˜ ์ฐฉ๊ฐ : move๋ฅผ ํ•œ๋‹ค๊ณ  ํ•ด์„œ..

  • 1๋ฒˆ) string ์—์„œ์˜ move
    -> move ๋ฅผ ํ–ˆ๋‹ค๊ณ  ํ•ด์„œ string s ์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์—†์–ด์ง€๋Š” ๊ฒƒ์ด์•„๋‹˜.
    string s ๊ฐ์ฒด์˜ ๋‚ด๋ถ€์˜ ์ž์›์ด ์ด๋™๋˜๋Š” ๊ฒƒ์ž„.
    --> 86๋ฒˆ ์ค„์—์„œ s๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์ž‰? ์•ˆ๋‚˜์˜ค๋„ค?
    ๋‚ด๋ถ€์˜ ์ž์›์ด ์˜ฎ๊ฒจ์ง„๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ. ์ฆ‰ string ํด๋ž˜์Šค์˜ char* ์˜ ์ž์›์ด ์ด์ „๋˜์—ˆ๋‹ค ๋ผ๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.
    ๊ทธ๋Ÿฐ๋ฐ s์˜ ์ฃผ์†Œ๋Š” ์—ฌ์ „ํžˆ ์กด์žฌํ•œ๋‹ค.

  • ์•„๋ž˜ ์„ค๋ช…์ด ์ด์ƒํ•˜๋‹ค... 240514

  • 2๋ฒˆ) ํด๋ž˜์Šค์—์„œ์˜ move
    : ๊ฐ์ฒด b๋ฅผ move ํ–ˆ์ง€๋งŒ, ์—ฌ์ „ํžˆ b์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ.
    -> ์˜๋„ํ•œ ๊ฑฐ๋Š” c์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ทธ๋Œ€๋กœ bํ•œํ…Œ ์ด๋™ํ• ์ค„ ์•Œ์•˜๋Š”๋ฐ. ์•„๋‹ˆ์—ˆ๋‹ค!

move์˜ ๋„์ž…

  • ์„ค๋ช…
    : ์ด๋ฆ„์žˆ๋Š” ๊ฐ์ฒด๊ฐ„์˜ ๋Œ€์ž… ๋ฐ ์ดˆ๊ธฐํ™”๋ฅผ ํ•˜๋ฉด ๋ณต์‚ฌ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋จ.
    Point p;
    Point p2 = p; -> Point(const Point&)
    ์™œ๋ƒํ•˜๋ฉด ์ด์ „์‹œ๊ฐ„์— ๋ฐฐ์šด ์ด๋™์ƒ์„ฑ์ž๋Š” ์ž„์‹œ๊ฐ์ฒด๊ฐ€ ์šฐ๋ณ€์— ์™€์•ผ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ.
    ๊ทธ๋Ÿฐ๋ฐ p ๊ฐ์ฒด๋Š” p2์— ๋Œ€์ž…ํ•œ ์ดํ›„์— ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด, ๊ตณ์ด
    ์œ„์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ง„ํ–‰ํ•ด์„œ ๋ณต์‚ฌ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•  ํ•„์š”๊ฐ€ ์—†์Œ.
    p๋ฅผ ํ• ๋‹นํ–ˆ์„ ๋•Œ ์ƒ์„ฑ๋œ ์ž์›๋“ค์„ p2์—๋‹ค๊ฐ€ ์ด๋™ ํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด
    p2๋ฅผ ๋ณต์‚ฌํ•˜๋ฉด์„œ ์ƒ์„ฑ๋˜๋Š” ์ž์›๋“ค์˜ ๋น„์šฉ์„ ์ ˆ์•ฝ ํ•  ์ˆ˜ ์žˆ์Œ.
  • move ์— ๋Œ€ํ•ด.
    : ๊ธฐ์กด์˜ lvalue์˜ ์ž์› ์ž์ฒด๋ฅผ ์ด์ „ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Œ.
    ์ด๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ‚ค์›Œ๋“œ๋กœ, lValue๋ฅผ rValue๋กœ ์บ์ŠคํŒ…์„ ํ•˜๊ฒŒ ๋˜๋ฉด, ์ด๋™์ƒ์„ฑ์ž๋‚˜,
    ์ด๋™๋Œ€์ž…์—ฐ์‚ฐ์ž๋กœ์˜ ํ˜ธ์ถœ์ด ๋ฐœ์ƒํ•จ.

์ฝ”๋“œ

  • -> move ๋‚˜ static_cast<&&> ์„ ์‚ฌ์šฉํ•˜์ž.
    : Point p;
    Point p2 = move(p); ๋˜๋Š” Point p2 = static_cast<Point&&>(p);
#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 pointer : " << 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 pointer : " << this << std::endl;

	}
	~Cat()
	{
		if (name != 0)
		{

			delete[] name;
			std::cout << this << " destructor" << "delete name! " << std::endl;
		}
		else
		{
			std::cout << this << " destructor " << " empty " << std::endl;
		}
	}

	void print()
	{
		std::cout << name << std::endl;
		std::cout << "==========" << std::endl;
	}

	Cat(Cat&& movObj)
	{
		std::cout << "move Call" << std::endl;
		name = movObj.name;
		age = movObj.age;
		std::cout << "this pointer : " << this << std::endl;
		movObj.name = 0;
	}
};

Cat foo()
{
	Cat c("naOng", 10);
	std::cout << "foo" << std::endl;
	std::cout <<  "this pointer : " << &c << std::endl;

	return c;
}

#include <string>
int main()
{
	Cat a("naong", 20); a.print();
	Cat b = a; b.print();
	Cat c = Cat("fairi", 40); c.print();
	Cat d = static_cast<Cat&&>(a); d.print();
	Cat e = b; e.print();

}
  • a๋ฅผ static_cast<nexon&&> ๋ฅผ ํ•˜๋ฉด ๋จ.
    -> move ์ƒ์„ฑ์ž๋ฅผ ๋ถˆ๋Ÿฌ๋‹ฌ๋ผ๋Š” ์˜๋ฏธ์ž„.
    : ๋งˆ์ง€๋ง‰ ์†Œ๋ฉธ์ž์—์„œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์ฃผ์†Œ๋ฅผ ๋ณด๋ฉด, ๋งจ์œ„์— ์ƒ์„ฑ์ž์—์„œ call ํ•œ Cat a์˜ ๋ฉ”๋ชจ๋ฆฌ ์ธ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ ,
    move ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, empty๋กœ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ.
  • ๋งค๋ฒˆ ์œ„์˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์ฝ”๋”ฉํ•˜๊ธฐ์—๋Š” ๋ถˆํŽธํ•ด์„œ move ํ‚ค์›Œ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ , ๋Œ€์ฒดํ•จ.
    : move(a);

  • ๊ฒฐ๊ณผ
    : c = Cat("fairi", 40) ์—์„œ move๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ตœ์ ํ™”๋ฅผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž„.


move์˜ ์˜๋ฏธ.

  • lvalue๋ผ๊ณ  ํ•˜๋”๋ผ๊ณ  rValue๋กœ ์บ์ŠคํŒ…ํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ, ์ด๋™์ƒ์„ฑ์ž๋‚˜ ์ด๋™๋Œ€์ž…์—ฐ์‚ฐ์ž๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•˜๊ฒ ๋‹ค ๋ผ๋Š” ์˜๋ฏธ์ž„!

  • move์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ static_cast์™€ &&๋ฅผ ํƒ€์ž…์œผ๋กœ ๋ช…์‹œํ•˜๋ฉด,
    ์ด๋™์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ.

  • ๊ทธ๋ฆผ 1๋ฒˆ
    : cc๋Š” lValue์ด์ง€๋งŒ, rValue๋กœ์˜ ํ˜•๋ณ€ํ™˜ ์ดํ›„ , ๋ฐ”๋กœ ๋Œ€์ž…์„ ํ†ตํ•ด ์ด๋™์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ.
    ๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ cc.print๋ฅผ ํ–ˆ๋Š”๋ฐ, ์ž์›์ด ์—†์Œ์ด ์ถœ๋ ฅ๋œ๋‹ค.

  • ๊ทธ๋ฆผ 2๋ฒˆ.
    : ์ด๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ํ‚ค์›Œ๋“œ move๊ฐ€ ์žˆ์Œ.

  • ๊ฒฐ๋ก 
    : ๊ทธ๋ฆผ 1๋ฒˆ๊ณผ 2๋ฒˆ ๋น„๊ตํ•˜๋‹ˆ๊นŒ, ๋‘˜๋‹ค ์ด๋™์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ.


์ค‘์š”! move ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด์„œ ์ด๋™์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒƒ์€ ์•„๋‹˜.

  • ์ƒ๋Œ€ ๊ฐ์ฒด ์—†์ด ๋‹จ๋…์œผ๋กœ move ํ–ˆ์„ ๋•Œ, ๋ณ€๋™์—†์Œ.

    ์ฆ‰, move๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ˆœ๊ฐ„์€ ์ƒˆ๋กœ์šด ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ดˆ๊ธฐํ™”๋‚˜
    ๋Œ€์ž…ํ•˜๋Š” ์ˆœ๊ฐ„์ž„.

์ด๋™ ๋Œ€์ž… ์—ฐ์‚ฐ์ž.

  • ์ดˆ๊ธฐํ™”์™€ ๋Œ€์ž…์€ ๋‹ค๋ฅธ ๊ฒƒ์ž„.
    -> ์•„๋ž˜ ์˜ค๋ฅ˜๋ฅผ ๋ณด๋ฉด, ๋Œ€์ž…์—ฐ์‚ฐ์ž๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์•„์„œ ์˜ค๋ฅ˜๊ฐ€ ์ƒ๊น€.
    ์ฆ‰ ๋ณต์‚ฌ ์ƒ์„ฑ์ž์™€ ๋ณต์‚ฌ ๋Œ€์ž…์—ฐ์‚ฐ์ž๋Š” ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ.

๊ฒฐ๋ก 

: ๋ณต์‚ฌ์ƒ์„ฑ์ž์™€ ์ด๋™์ƒ์„ฑ์ž 2๊ฐœ๋ฅผ ๋ชจ๋‘ ๋งŒ๋“œ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ.
๋Œ€์ž…์—ฐ์‚ฐ์ž์™€ ์ด๋™์—ฐ์‚ฐ์ž๋ฅผ ๋ชจ๋‘ ๋งŒ๋“ค์–ด์ฃผ์ž.

  • ์˜ˆ์ œ
int main()
{
	point p;
    point p1;
    p1 = move(p);
}

problem

: ๋ณต์‚ฌ ๋Œ€์ž…๊ณผ ์ด๋™ ๋Œ€์ž…์„ ๋งŒ๋“ค์–ด๋ผ.

  • ๊ฐ€) ๋ณต์‚ฌ ๋Œ€์ž…์—ฐ์‚ฐ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ
    : ๋ณต์‚ฌ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฉ”๋ชจ๋ฆฌ ์ฆ๊ฐ€ํ•จ.
  • ๋‚˜) ์ด๋™ ๋Œ€์ž…์—ฐ์‚ฐ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ
    : ์ž์›์„ ์ด๋™ํ–ˆ๊ณ , ํ•ด์ œํ•˜๊ธฐ ๋ฌธ์ž๋„ ๋„ ๋‚˜ํƒ€๋‚˜๋Š”ใ… ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ.

  • ์ฝ”๋“œ

// cppTest.cpp : ์ด ํŒŒ์ผ์—๋Š” 'main' ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์„œ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์ด ์‹œ์ž‘๋˜๊ณ  ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
//

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class Cat
{
private : 
	char* name;
	int age;
public : 
	Cat(const char* _name, int _age)
		: age(_age)
	{
		name = new char[strlen(_name) + 1];
		strcpy(name, _name);
	}

	Cat(const Cat& _obj)
		: age{_obj.age}
	{
		name = new char[strlen(_obj.name) + 1];
		strcpy(name, _obj.name);
		cout << "copy" << endl;
		cout << "name ๋ฉ”๋ชจ๋ฆฌ ์ฆ๊ฐ€" << endl;
	}	
	void print() const
	{
		if (name == 0)
			cout << "์ž์›์ด ์—†์Œ." << endl;
		else
			cout << name << endl;
	}
	Cat(Cat&& _cat)
		: name{ _cat.name }, age{ _cat.age }
	{
		_cat.name = 0;
		cout << "move constructor" << endl;
	}

	~Cat() {
		delete[] name;
		if (name != 0)
			cout << "ํ•ด์ œํ•˜๊ธฐ" << endl;
	}

	Cat& operator=(const Cat& _obj)
	{
		age = _obj.age;
		name = new char[strlen(_obj.name) + 1];
		strcpy(name, _obj.name);
		cout << "copy" << endl;
		cout << "name ๋ฉ”๋ชจ๋ฆฌ ์ฆ๊ฐ€" << endl;
		return *this;
	}

	Cat& operator=(Cat&& _obj)
	{
		age = _obj.age;
		name = _obj.name;
		_obj.name = 0;
		cout << "move =" << endl;
		return *this;
	}
};

Cat foo()
{
	Cat c("bom", 10); return c;
}

int main()
{
	Cat cc("bomi",10);
	Cat c2("zzokki", 20);
	c2 = cc;
	cc.print();
	c2.print();
	cout << "hello" << endl;
}

์ˆ™์ง€ํ•ด์•ผ ํ• ์ .

๋ณต์‚ฌ ๋Œ€์ž…์—ฐ์‚ฐ์ž์™€ ์ด๋™ ๋Œ€์ž…์—ฐ์‚ฐ์ž ๋ชจ๋‘ ์ž„์‹œ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„
๋ง‰๊ธฐ ์œ„ํ•ด์„œ ์ฐธ์กฐ๋กœ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•จ.

profile
๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ

0๊ฐœ์˜ ๋Œ“๊ธ€