전체 글93 [ C++ ] 깊은 복사( deep copy )와 얕은 복사 ( shallow copy ) 얕은 복사( shallow copy )는 디폴트 복사 생성자에 의한 멤버 대 멤버의 복사 방식을 말한다. 하지만 이는 멤버 변수가 힙의 메모리 공간을 참조하는 경우에 문제가 된다. 예를 보자. A형 객체 a와 b가 있고, a는 객체 생성 시 초기화를 했다. 반면 b는 a의 디폴트 복사생성자에 의해 멤버 대 멤버 복사가 일어났다. 즉, 얕은 복사가 일어났다. 근데 예상된 결과와는 다르게 소멸자 호출이 한번 일어났다. 이유는 char형 포인터인 name 때문이다. 멤버 대 멤버 복사이기 때문에 객체 a의 name을 가리키는 주소 값을 b도 같이 할당받아, 두 객체가 같은 문자열을 참조하는 문제가 생긴다. 그래서 만약 객체 a가 먼저 소멸된다고 가정하면, a의 소멸자 호출이 일어나면 name을 delete 해.. 2019. 9. 26. [ C++ ] 복사 생성자( Copy Constructor )와 explicit 복사 생성자 ( Copy Constructor )는 무엇일까? 일단 복사라는 말에 주목해보자. 우리가 변수의 값을 다른 변수에 복사를 하려면 다음과 같이 쓴다. int num1 = 5; int num2 = num1; 하지만 C++에서는 다음 방식과 동일하게 선언과 초기화를 지원한다. int num1(5); int num2(num1); 그럼 객체는 어떻게 될까? A a; A b = a; A라는 클래스가 있고, a와 b 객체가 있다. 그럼 위와 같은 코드는 다음과도 동일하다. A a; A b(a); 즉, b객체를 새로 생성해서, a와 b가 멤버 대 멤버 복사가 일어난다. 근데 b의 생성자는 어떻게 호출이 될까? 일단 여기를 다시 해석해보자. A b(a); - A형 객체를 생성. - 객체의 이름은 b. - a.. 2019. 9. 24. [ C++ ] 생성자와 소멸자 그리고 멤버 이니셜라이저( Member Initializer ) 생성자(constructor)는 객체 생성 시 딱 한번 호출된다. 또한 클래스의 이름과 함수의 이름이 동일하고 반환형이 선언되어 있지 않으며, 실제로 반환하지 않는다. 또한 생성자도 함수이기에 오버 로딩과 매개변수에 디폴트 값 설정도 가능하다. 하지만 이렇게 생성자를 통해서 멤버변수를 초기화하는 것은 불편하기에 C++은 멤버 이니셜라이저(Member Initializer)도 지원한다. 멤버(Member)는 클래스 내의 멤버 변수 혹은 멤버 변수를 뜻하고 이니셜 라이저(Initializer)는 초기화라는 뜻이다. 그러면 초기화를 어떻게 하는지 살펴보면 이렇게 생성자 함수 뒤에 : 를 붙여서 사용하면 된다. num(A_num)은 num = A_num과 동일한 의미를 가진다. "즉, 멤버 이니셜 라이저를 사용.. 2019. 9. 24. [ C++ ] 참조자에 대하여 변수는 할당된 메모리 공간에 붙여진 이름이다. int a = 10; 이와같이 변수 a는 값 10이 할당된 공간을 가르키는 이름이 되었다. 하지만 저 공간에 이름을 더 많이 부여할 수 없을까? 참조자는 자신이 참조하는 변수를 대신할 수 있는 또 하나의 이름이다. ( 별명이라고 생각하면 쉬울 것 같다. ) int a = 10; int &ref = a; 참조자를 생성할 때는 변수 앞에 &연산자를 붙이고 선언시 해당 변수로 초기화하면 된다. 주의할 점은, 참조자는 한번 지정한 객체를 변경할 수 없다. 자, 그럼 참조에 대해 더 알아보자. 변수 a를 참조자 ref가 참조하게 된다. 그렇다면 대입연산의 과정에서 참조자 ref에 무엇이 전달된다고 해야 할까? "변수 a를 참조할 수 있는 참조의 정보가 전달된다." 즉.. 2019. 9. 23. [ C++ ] Self-Reference Self-Reference란 객체 자신을 참조할 수 있는 참조자를 의미한다. this 포인터를 이용하면 객체가 자기 자신의 참조에 사용 가능한 참조자의 반환문을 작성할 수 있다. GetRef 함수를 통해 Self-Reference의 반환이 일어난다. 다음과 같이 b객체가 a객체의 참조자가 되어서 멤버변수 num에 대한 영향을 같이 받고있다. 2019. 9. 20. [ C++ ] C/ C++ 입출력 함수별 속도 비교 알고리즘 문제를 풀 때 참고하자. - std::ios::syne_with_stdio(false)는 cin과 cout의 속도를 과속하는 반면에 C 표준 입출력 사용이 불가능하기에 현업에서는 사용하지 말자. - endl; 대신에 개행문자 '\n' 을 사용하면 flush가 불필요하게 호출되지 않아 속도가 줄어든다. 2019. 9. 20. [ C++ ] 객체 배열과 객체 포인터 배열 / this 포인터 객체 배열과 객체 포인터배열은 구조체 배열과 구조체 포인터배열와 유사하다. 객체 배열은 다음과 같은 형태로 선언을 한다. A arr[10]; A는 클래스 이름이다. 그럼 객체 배열을 선언시 생성자가 어떻게 동작하는지 살펴보면 위와 같은 결과를 볼 수 있다. 즉, 위 소스코드의 경우에는 arr가 10개의 객체를 담는 객체 배열이라고 볼 수 있다. 객체 포인터 배열은 객체의 주소를 담는 배열이다. 선언은 다음과 같은 형태로 하면 된다. A * arr = new A[10]; 위를 보면 각 인덱스에 객체가 생성된 것을 확인할 수 있다. this는 객체 자신을 가리키는 포인터이다. 아래의 소스코드를 보면 알 수 있다. GetPoint를 통해서 b가 a의 주소값을 얻은 걸 확인할 수 있다. 이렇게 this는 객체 .. 2019. 9. 20. [ C++ ] 구조체와 클래스의 차이점 - 구조체에 선언된 변수와 함수에 별도의 접근제어 지시자를 선언하지 않으면, public으로 선언된다. - 클래스에 선언된 변수와 함수에 별도의 접근제어 지시자를 선언하지 않으면, private으로 선언된다. 위 내용이 구조체와 클래스의 유일한 차이점이라고 Effective STL에 나와있다. 2019. 9. 20. [ C++ ] 파일 분할 하나의 프로그램을 만들 때 하나의 소스파일에 모든 내용을 적진 않는다. 특히 C++에서는 클래스의 선언과 정의를 분리하는 경우가 많다. 클래스의 선언(declearation)은 클래스를 구성하는 외형적인 틀을 보여준다. 예로 들어서 거북이에 관한 클래스가 있다고 하자. ( 글쓴이는 거북이를 많이 좋아한다. ) #ifndef __TURTLE_H__ #define __TURTLE_H__ namespace TURTLE_CONST { enum { NAME_LEN = 20, SPEED = 100 } } class Turtle { private: char turtle_name[TURTLE_CONST::NAME_LEN]; int speed; public: void InitMembers(char.. 2019. 9. 20. 이전 1 ··· 5 6 7 8 9 10 11 다음