inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문

연산자 오버로딩 #1

생성자 질문(타입 변환 생성자)

383

starkshn

작성한 질문수 134

0

opertor를 공부하면서 생성자 부분이 궁금해서 테스트를 해보았는데

class Player
{
public :
    int m_iHp;
    int m_iAttack;
    int m_iDefense;

public:
    Player()
        :
        m_iHp(100),
        m_iAttack(20),
        m_iDefense(5)
    {
        cout << "Player 기본 생성자!" << endl;
    }

    Player(int id)
        :
        m_iHp(200),
        m_iAttack(40),
        m_iDefense(10)
    {
        cout << "Player ID 받는 버젼 생성자!" << endl;
    }
    ~Player()
    {
        cout << "Player 소멸자!" << endl;
    }
};


class Knight : public Player
{
public:
    int m_iStat;

public:
    Knight()
        :
        m_iStat(10)
    {
        cout << "Knight 기본 생성자!" << endl;
    }
    Knight(int id)
        :
        Player(id),
        m_iStat(20)
    {
        cout << "Knight id 받는 버젼 생성자!" << endl;
    }
    ~Knight()
    {
        cout << "Knight 소멸자!" << endl;
    }

};


int main()
{
    Knight k1;
    k1 = 3;


    return 0;
}

현재 Knight k1을 만들게 되면은

콘솔창에 출력문이 이렇게 찍혀 햇갈리는 부분이 있어서 질문드립니다.

 

메모리를 확인해보니

k1의 주소(0x000000718D0FF688)는 이런값으로 안에 데이터들이 스택에 자리를 차지하게되어있었습니다.

이후 k1 = 3; 를 하게되면

Knight k1의 스택에 있는 주소가 가르키는 값들이 변경이 되는데 이는,

타입 변환 생성자(기타 생성자)를 통해 만들어진 객체를

만들어서 

"암시적 형변환"으로 만들어진 객체를 대입연산자로 k1의 주소에

멤버 변수 하나하나를 다 덮어 쓴 형태인거같더라구요

 

즉,  정리하자면

1) Knight k1; 을 하는 순간은 스택에 기본 생성자를 호출 한 상태로 올라간다.

 

2) k1 = 3 하였을 경우, 컴파일러가 암시적 형변환으로

인자를 하나를 받는 Knight의 타입 변환 생성자(기타 생성자)를 호출한뒤

k1의 주소에 '=' 연산자를 통해 멤버 변수 하나하나를 덮어쓴다. (얕은 복사)

 

여기서 궁금한점이

소멸자를 출력하는 문장이 두줄에 걸쳐서 나오는게 아니라

이런식으로 4줄에 걸쳐서 나오는데

이게 분명히 암시적 형변환으로 생성한 객체를 생성하고 

기본생성자로 만든 k1에 멤버 변수들을 덮어썻다고 생각해서 

스택에는 Knight의 객체가 하나밖에 없는 상태로 봤는데

 

콘솔창을 확인하면 k1뿐만 아니라 

k1 = 3을 하였을 때의 3에 해당하는 객체도 어딘가에 존재를 하는거 같은데

3이라는 정수를 컴파일러가 타입변환 생성자로 받아들여서 

인자를 하나만 받는 Knight객체를 만들어서 '=' 연산자를 통해 k1에다가 멤버 변수를 다 덮어 씌우는데

정수 3을통해서 만들어진 객체도 스택에 올라간 다음에

값만 k1이라는 객체에 덮어 씌우는건가요..??

 

맞는말인가요..???

C++

답변 3

0

피로한 문어

3이라는 정수를 컴파일러가 타입변환 생성자로 받아들여서 

인자를 하나만 받는 Knight객체를 만들어서 '=' 연산자를 통해 k1에다가 멤버 변수를 다 덮어 씌우는데

정수 3을통해서 만들어진 객체도 스택에 올라간 다음에

값만 k1이라는 객체에 덮어 씌우는건가요

-> 제가 알아본 바로는 이게 맞습니다. 그리고 타입변환 생성자로 만들어진 임시 객체는 k1=3; 대입 직후에 쓸모가 없어지므로 임시 객체에 대한 소멸자가 호출됩니다.
그리고 k1을 생성한 이후의 k1=3; 대입은 대입 연산자입니다.

0

starkshn

Knight k1 = 3; 같은경우는

타입 변환생성자(인자를 하나받는 생성자) 호출하여 객체를 만드는 것이고(생성자 한번만 호출)

 

Knight k1;

k1 = 3 일경우에는

 

먼저 "기본생성자" 호출하여 객체(k1) 만든뒤,

 

인자를 하나만 받는 생성자(타입 변환생성자 ) 호출하여 객체(3) 만든뒤(임시객체 생성)

 

(암시적 형변환을 제한하고싶다면 인자를 하나만 받는 생성자 앞에 explicit 키워드 붙이기)

 

기본생성자를 호출하여 만들어진 k1

 

= 3; 이것이

 

k1 복사 대입 연산자" 수행한것인가요?

 

0

Rookiss

C++이 정말 문법이 지저분한게
Knight k1 = 3; 을 할 때와

Knight k1;
k1 = 3;을 할 때의 의미가 완전히 다릅니다.

전자라면 k1에 int 생성자를 호출하겠지만,
후자는 임시 객체를 만든 다음 복사가 일어나기 때문에
임시 객체의 소멸자, 그리고 k1의 소멸자가 두 번 호출된 것이죠.



visualstudio에서 파일분할관리실습시 설정 문의를 드립니다.

0

546

1

정렬함수 좀 더 확실하게 이해 할 방법이 있을까요?

0

445

1

strcpy() 구현 관련 질문

0

519

1

빌드(망치)를 누르니 이런 오류가 떴습니다. 어떻게 해야 하나요?

0

461

1

클래스 타입의 포인터 질문합니다

0

550

1

입력값을 enum 값에 넣어주는거 이제 막혔나요?

0

501

1

템플릿 특수화 관련 질문

0

387

1

포인터 관련 질문합니다!

0

267

1

Unable to start assembler. Check your settings.

0

840

2

cpu선택

0

543

1

포인터 질문이 있습니다

0

330

1

20:35 에서 구조체 크기에 대한 질문입니다!

0

588

1

iterator 삭제관련

0

410

1

함수 호출을 디스어셈블러로 분석하다가 궁금점이 생겼습니다!

0

315

1

15 분 45초 대 질문

0

312

0

스택 프레임 질문합니다!

2

309

1

오른값 참조 in 게임

0

387

0

동적할당 질문이 있습니다

0

452

1

안녕하세요 메모리에 대해 질문드립니다.

0

309

1

함수객체 의 매개변수

0

365

1

복사생성자

0

439

1

main이나 endl 부분이 주황색으로 표시된건 어떻게 하나요

0

426

1

포인터 실습 강의를 보고 궁금한게 있습니다.

0

358

1

스택 오버플로우

2

794

1