🧠
Hi, Daehuyn Lee
  • Fork-my-brain
  • Network
    • 7. "데이터가 전달되는 원리" OSI 7계층 모델과 TCP:IP 모델
    • [Netwhat] 연습문제 정리
    • 11. IP 라우팅(routing) 동작 과정
    • 3. IP address 란?
    • 2. 컴퓨터 구조를 통해 이해하는 파일(File)과 소켓(Socket)
    • 10 "더 편리한 인터넷을 위해" DHCP && DNS 프로토콜
    • 9. 데이터? 세그먼트? 패킷? 헷갈릴 땐 PDU를 알아보자
    • 8. TCP 와 UDP 차이를 자세히 알아보자
    • 5. 서브넷팅(subnetting)으로 네크워크를 효율적으로 관리하자
    • 4. 넷마스크(Netmask)와 서브넷마스크(Subnetmask)
    • 1. 비유로 이해하는 컴퓨터 구조
    • 6. 공인(Public) && 사설(Private) IP의 차이점
  • Django
    • [Django 1] 가상환경에 Django 설치하기
    • [Django 3] Hello World 웹사이트 만들기
    • [Django 9] static 으로 css 로드하기
    • [Django 10] 한 템플릿에서 복수의 css 파일 적용하기
    • [Django 11] URL app별로 관리하기
    • [Django 8] 템플릿 상속
    • [Django 4] MTV 패턴
    • [Django 6] 블로그 model 만들기
    • [Django 2] Django는 어떻게 작동할까
    • [Django 7] '새 글 작성' 기능 만들기
    • [Django 5] 템플릿 언어
  • Projects
    • 예발자닷컴
      • 4. 프론트엔드의 역할은 어디까지 - 더미데이터 만들기
      • 7. [React 리팩토링] CSS Inline Styling에 Props 사용하기
      • 6. [React 리팩토링] JSX에서 조건문 사용해 렌더링하기
      • 3. 예발자닷컴 프론트서버 업데이트 하기
      • 8. [React 리팩토링] 예발자 프로젝트에 Redux 적용하기
      • 5. [React 리팩토링] JSX로 HTML 렌더링하기
      • 1. 👨‍👨‍👦‍👦 Github로 협업 프로젝트 관리하기
      • 2. React Component를 활용한 웹페이지 디자인 연습
  • Git
    • [Git] Interactive Rebase 실습
    • 오픈소스 개발 참여에 필요한 Git 명령어 정리
    • 개발자가 오픈소스를 읽는 방법
    • 오픈소스 프로젝트 시작하기
    • SSH agent ; Passphrase 입력 없이 Push하기
    • SSH로 원격저장소 접속하기
    • [Github] 개인 저장소를 팀 저장소로 변경하기
    • GitHub Dependabot
    • Git add, commit, push 취소하기
    • 깃헙 잔디 관리 팁
    • 원격저장소 여러개 연결하기
    • Typora(마크다운 에디터) 사용법
  • C
    • C Piscine
      • 메모리 구조를 알아보자
      • Makefile 만들기
      • GCC로 정적 라이브러리 파일 만들기
      • 외부 라이브러리 GCC로 컴파일 하기
      • 정적(Static) 변수
      • 저수준 파일 입출력
      • Makefile 자주 사용하는 문법 정리
      • segmentation fault 해결하기
      • C의 구조체 개념
      • 연결 리스트(linked list)에서 이중 포인터 사용하기
      • 로컬에 Norminette 설치하기
    • GetNextLine
      • [GetNextLine] 과제소개-Reading a line on a fd is way too tedious
      • [GetNextLine] 삽질의 기록
      • [GetNextLine] 리팩토링-프로그램의 목적을 고려한 코드
    • ft_printf
      • 1. 과제소개
      • 2. 가변인자 (Variadic Arguments)
      • 3. 형식태그와 서식지정자 printf 함수의 옵션 알아보기
    • Libft
      • [Libft] Bonus
      • [Libft] Test Program
      • [Libft] 나만의 C 라이브러리 만들기
      • [Libft] Part 2
      • [Libft] Part 1
  • UNIX shell
    • [minishell] 4. 종료상태와 에러메세지 처리
    • [minishell] 1. 과제소개 및 선행지식
    • [minishell] 2. 프로그램 구조 및 개발 기록들
    • [minishell] 5. 파이프(Pipe) 처리
    • [minishell] 3. 시그널(Signal) 처리하기
    • [minishell] 6. 리다이렉션(Redirection) 처리
  • Web
    • Next.js
      • [Next.js] CSS모듈과 복수의 class 사용하기
    • Node.js
      • [Node.js] 웹페이지에 파일 띄우기
      • [Node.js] URL에서 쿼리스트링 추출하기
      • [Node.js] '새 글 작성' 페이지 만들기
    • React
      • [React] 2. 컴포넌트(Component) 생성 및 파일별로 분리하기
      • [React] 1. 파일 구조 이해하기
      • [React] 4. 컴포넌트의 State 란
      • [React] 3. 컴포넌트의 Props 란
    • Javascript
      • Click, Enter 두 개의 이벤트 동시에 등록하기
      • Click eventListener 등록하기
      • JavaScript & C 문법 비교
      • JavaScript 객체 지향의 특징
    • CSS
      • [CSS] box-model, display, position
  • Docker
    • ft_server
      • 2. 도커 설치부터 워드프레스 구축까지
      • 1. 선행지식-Docker? Debian Buster? Nginx? ...
      • 3. Dockerfile 만들기
  • Kubernetes
    • 🌌[쿠버네티스 아키텍처] 3. API 호출
    • 🌌[쿠버네티스 아키텍처] 1. 구성 및 설계
    • 🌌[쿠버네티스 아키텍처] 2. 오브젝트 (Objects)
  • Operating System
    • Philosophers
      • [Philosophers] 예시예제로 보는 뮤텍스와 세마포어의 차이
      • [Philosophers] 식사하는 철학자 문제 소개
  • CPP
    • [CPP-08] STL containers, iterators, algorithms
    • [CPP-06] CPP 형변환 연산자
    • [CPP-04 ex02] 인터페이스(Interface) 클래스
    • [CPP-04 ex00] 다형성(Polymorphism) 및 가상함수
    • [CPP-02] Canonical 클래스 복사 생성자와 대입 연산자 오버로딩
    • [CPP-07] Templates
    • [CPP-01] this 포인터와 문자열 스트림(stringstream)
    • [CPP-01] 클래스의 정적할당과 동적할당 new, delete
    • [CPP-01] 파일 입출력 및 문자열 치환하기
    • [CPP-01] 참조자(reference)와 포인터는 다르다
    • [CPP-02] 정수부동소수값 - 고정소수값 변환
    • [CPP-04 ex01] 추상 클래스의 필요성 순수 가상함수
    • [CPP-00] Megaphone! CPP 표준입출력
    • [CPP-03] (ClapTrap이 뭐지) 다중 상속과 가상 상속
    • [CPP-05] 예외 처리 (exception handling)
    • [CPP-00] 객체지향의 관점으로 클래스 이해하기
    • [CPP-01] 랜덤값 얻기
  • IBM Cloud
    • [IBM Cloud] 1. 클라우드 컴퓨팅 개요
    • [IBM Cloud] 5. 클라우드 컴퓨팅의 구성 요소
    • [IBM Cloud] 3. 클라우드 서비스 모델 및 배포 모델
    • [IBM Cloud] 2. 클라우드를 활용하는 새 기술들
    • [IBM Cloud] 4. 떠오르는 클라우드 트렌드
    • [IBM Cloud] 6. 클라우드 스토리지 유형 및 CDN
  • Assembly
    • [libasm] 어셈블리 프로그램 구조와 x64 레지스터 이해하기
    • [libasm] strlen 함수를 어셈블리어로 짠다면
    • [libasm] 어셈블리 명령어(opcode) 정리
Powered by GitBook
On this page
  • tags: ["42Seoul","Canonical","Coplien","cpp","대입 연산자 오버로딩","복사 생성자"]
  • 1. Canonical 클래스
  • 2. 복사 생성자
  • 2.1. 얕은 복사(Shallow Copy)
  • 2.2. 깊은 복사(Deep Copy)
  • 3. 대입 연산자 오버로딩
  • 3.1. 오버로딩이란?
  • 3.2. 연산자 오버로딩 방법
  • 3.4. 연산자 오버로딩 호출 시점
  • 3.4. 주의점
  • 4. 정리

Was this helpful?

  1. CPP

[CPP-02] Canonical 클래스 복사 생성자와 대입 연산자 오버로딩

title: "[CPP-02] Canonical 클래스: 복사 생성자와 대입 연산자 오버로딩" description: "canonical이란, "규정대로"하는 프로그래밍을 의미한다. 앞으로의 CPP 과제는 Coplien form 규정대로 클래스를 작성해야한다." date: 2021-04-25T02:45:49.606Z

tags: ["42Seoul","Canonical","Coplien","cpp","대입 연산자 오버로딩","복사 생성자"]

[CPP-Module/ex00: My First Canonical Class 과제] You are going to discover a new and awesome number type: fixed point numbers! Write a canonical Fixed class to represent fixed point numbers:

Private members:

  • int : 고정 소수값을 저장

  • static const int : 항상 8 글자의 값을 가지는 fractional bits가 저장

Public members:

  • default 생성자

  • 소멸자

  • 복사 생성자

  • 대입 연산자 오버로딩

  • getRawBits(void) const

  • setRawBits(int const raw)

1. Canonical 클래스

From now on, each class you write MUST be in canonical (Coplien) form: At least one default constructor, a copy contructor, an assignation operator overload and a destructor. We won’t ask again.

canonical이란, "규정대로"하는 프로그래밍을 의미하며, 반대로 non-canonical이란 "규정에 따르지 않고"하는 프로그래밍을 의미한다. 일종의 코딩 컨벤션같다. 앞으로는 과제를 진행할 때 Coplien form 규정대로 클래스를 작성해야한다.

  1. 디폴트 생성자

  2. 복사 생성자

  3. 할당 연산자 오버로딩

  4. 소멸자

위 네 가지 멤버는 그것이 사용되던 안되던 항상 클래스에 정의되어야 한다. 생성자와 소멸자는 알겠는데 복사 생성자와 대입 연산자 오버로딩은 생소한 개념이다.

2. 복사 생성자

Fixed::Fixed(const Fixed& fixed) //선언
Fixed a;
Fixed b(a); // a를 복사해 b를 생성했다.

상수로 선언된 참조자이며, type은 클래스(자기 자신)가 된다. 복사 생성자는 기존 값을 복사해 전달해주는 개념이라 값이 바뀌어서는 안된다. 따라서 const로 선언한다.

  • 정의하지 않으면 디폴트 복사 생성자가 생긴다.

  • 디폴트 복사 생성자는 얕은 복사를 한다.

  • 복사생성자를 새로 정의했다고해서 다 깊은 복사인 것은 아니다. 깊은 복사를 하고 싶다면 복사 생성자 내에 동적 할당된 새 객체가 있어야 한다.

2.1. 얕은 복사(Shallow Copy)

  • 객체를 복사할 때, 해당 객체만 복사하여 새 객체를 생성한다.

  • 복사된 객체의 인스턴스 변수는 원본 객체의 인스턴스 변수와 같은 메모리 주소를 참조한다.

  • 따라서 해당 메모리 주소의 값이 변경되면 원본 객체 및 복사 객체의 인스턴스 변수 값은 같이 변경된다.

2.2. 깊은 복사(Deep Copy)

  • 객체를 복사 할 때, 해당 객체와 인스턴스 변수까지 복사하는 방식.

  • 전부를 복사하여 새 주소에 담기 때문에 참조를 공유하지 않는다.

3. 대입 연산자 오버로딩

3.1. 오버로딩이란?

CPP에는 오버로드라는 개념이 존재한다. C와는 다르게, 함수의 이름이 같아도 매개변수가 다르면 선언 및 정의가 가능하다. 지금까지 이 개념을 이용해 조건에 따라 다른 기능을 하도록 생성자를 여러개 만들 수 있었던 것이다. 즉 오버로드는, 같은 객체지만 다른 기능을 하도록 만든다는 의미다.

그렇다면 연산자 오버 로딩이란 기존의 연산자를 재정의하는 것이라고도 볼 수 있다. 원래 객체끼리는 + 같은 연산자를 사용할 수 없는 것이 일반적이다. 하지만 연산자 오버로딩을 통해 +의 기능을 재정의 해준다면, 객체가 기본 자료형 변수처럼 덧셈, 뺄셈, 혹은 곱셈과 같은 연산들을 할 수 있도록 만들 수 있다. 이렇게 되면 객체도 기본 자료형 데이터처럼 취급하는 것이 가능하다.

3.2. 연산자 오버로딩 방법

Fixed& operator=(const Fixed& fixed);

연산자 오버 로딩을 하기 위해서는 operator 키워드와 연산자를 묶어서 함수의 이름을 정의하면, 연산자를 이용한 함수의 호출이 가능하다.

위 예제처럼 클래스 내부에 연산자 오버로딩을 선언하면, 클래스 멤버 함수에서 오버로딩된 = 을 사용할 수 있다.

예를 들어 아래 복사 생성자

Fixed::Fixed(const Fixed& fixed)
{
    std::cout << "Copy constructor called" << std::endl;
    *this = fixed;
}

*this = fixed; 는 왼쪽의 *this 객체를 대상으로 operator= 함수를 호출하면서 오른쪽 피연산자인 객체 fixed를 인자로 전달한다는 의미를 가진다.

  • 정의하지 않으면 디폴트 대입 생성자가 생긴다.

  • 디폴트 대입 생성자는 얕은 복사를 한다.

  • 대입 생성자 내에서 동적 할당을 하거나 깊은 복사가 필요하면 직접 정의를 해야 한다.

3.4. 연산자 오버로딩 호출 시점

아니 그러면, 이 프로그램 내의 모든 코드에서 = 연산이 재정의 되는건가? 하는 의문을 가질 수 있다. 원래 기능인 대입 연산도 필요하고, 객체를 복사할 때도 = 가 필요한데 말이다.

사실, 복사 생성자와 대입 연산자 오버로딩은 유사하지만 호출되는 시점이 다르다. 복사 생성자는 객체가 새로 생성되는 시점에서 대입을 할 때 호출이 되고 대입 연산자 오버로드는 객체 두 개가 이미 생성 및 초기화 진행된 상태에서 올바른 인자를 대입 할 때 호출이 된다.

즉, 연산자 오버로딩 함수의 매개변수를 특정 객체로 선언했다면, = 연산자 오른쪽에 그 객체가 들어왔을 때만 연산자가 오버로드 된다.

3.4. 주의점

연산자 내에 동적 할당이 된 경우에는 이전에 동적 할당되었던 데이터를 해제해야 한다. 그렇지 않으면 기존에 있던 데이터가 소멸되지 않아 메모리 누수가 생긴다.

4. 정리

int main(void)
{
    Fixed a;
    Fixed b(a);
    Fixed c;

    c = b;

    std::cout << a.getRawBits() << std::endl;
    std::cout << b.getRawBits() << std::endl;
    std::cout << c.getRawBits() << std::endl;

    return 0;
}
//console
Default constructor called //a 생성
Copy constructor called // b 생성
Assignation operator called // *this = fixed;
getRawBits member function called // fixed.getRawBits();
Default constructor called //c 생성
Assignation operator called //c = b
getRawBits member function called // fixed.getRawBits();
getRawBits member function called
0
getRawBits member function called
0
getRawBits member function called
0
Destructor called
Destructor called
Destructor called
Previous[CPP-04 ex00] 다형성(Polymorphism) 및 가상함수Next[CPP-07] Templates

Last updated 3 years ago

Was this helpful?