public 상속의 의미는 is-a이다. 기본 클래스에 적용되는 모든 것들이 파생 클래스에 그대로 적용되어야 한다. 왜냐하면 모든 파생 클래스 객체는 기본 클래스 객체의 일종이기 때문이다. public 상속 모형은 반드시 is-a public 상속은 is-a이다. 이 사실을 무조건 기억해야 한다. B(Base) 클래스로부터 D(Derived) 클래스를 파생시켰다면, D 타입으로 만들어진 모든 객체는 B타입의 객체이지만, 그 반대는 되지 않는다. 다시 말해 B는 D보다 더 일반적인 개념을 나타내며, D는 B보다 더 특수한 개념을 나타낸다. B타입의 객체가 쓰일 수 있는 곳에는 D타입의 객체가 쓰일 수 있다. D타입의 모든 객체는 B타입의 객체도 되기 때문이다. C++은 public 상속의 문법은 다음과 같..
C++
컴파일 의존성을 최소화하는 작업의 배경이 되는 가장 기본적인 아이디어는 정의 대신에 선언에 의존하게 만드는 것이다. 이러한 방법으로는 핸들클래스와 인터페이스 클래스이다. 라이브러리 헤더는 그 자체로 모든 것을 갖추어야 하며 선언부만 갖고 있는 형태여야 한다. 이 규칙은 템플릿의 여부와 관계없이 동일하게 적용해야 한다. 파일 사이의 컴파일 의존성을 최대로 줄이자 C++은 헤더와 구현부를 두 파일로 분리하여 구현하는 것이 일반적이다. 프로그램의 규모가 커지면 여러 개의 파일이 존재할 것이다. 그러다 보면 파일들 사이의 컴파일 의존성이 올라가 빌드 속도도 느려지고 에러가 발생할 여지가 생긴다. class Person { public: Person(const std::string& name, const Date..
어떤 객체의 내부요소에 대한 핸들을 반환하는 것은 되도록 피해라. 캡슐화 정도를 높이고, 상수 멤버 함수가 객체의 상수성을 유지한 채로 동작할 수 있도록 하며, 무효참조 핸들이 생기는 경우를 최소화할 수 있다. 내부에서 사용하는 객체에 대한 핸들을 반환하지 마라 내부에서 사용하는 객체를 제어할 수 있는 핸들을 반환하는 것은 좋지 않다. 사각형을 사용하는 어떤 응용프로그램을 만들고 있다고 가정해 보자. 사각형은 좌측 상단과 우측 하단의 꼭짓점 두 개로 나타낼 수 있다. 이것을 추상화한 Rectangle 클래스를 만들었다. 메모리 부담을 줄이기 위해 꼭짓점을 Rectangle 자체에 넣는 것이 아니라 별도의 구조체로 관리하기로 했다. class Point { public: Point(int x, int y)..
캐스팅은 되도록 하지 마라. 특히 수행 성능에 민감한 코드에서 dynamic_cast는 더욱 하지 마라. 캐스팅이 어쩔 수 없이 필요하다면, 함수 안에 숨길 수 있는지 확인해라. 가능하다면 최소한 사용자는 자신의 코드에 캐스팅을 넣지 않는 대신 함수를 호출하여 처리할 수 있다. 구형 스타일의 캐스트를 쓰려거든 C++ 스타일의 캐스트를 선호해라. 더욱 읽기 좋은 코드가 된다. 캐스팅은 되도록 하지 마라 C++에서는 어떤 일이 있어도 타입 에러가 생기지 않도록 보장해야 한다. 타입 에러가 발생하는 원인 중 가장 큰 것이 바로 캐스트(cast)이다. 일단 캐스팅 문법을 정리하면 다음과 같다. (T) 표현식: 표현식 부분을 T타입으로 캐스팅 T(표현식): 표현식 부분을 T타입으로 캐스팅 이 두 개는 C에서 사용..
변수 정의는 늦출 수 있을 때까지 늦춰라. 프로그램도 깔끔해지고 효율도 좋아진다. 변수 정의는 최대한 늦게 변수를 정의할 때 반드시 들어가는 비용이 있다. 바로 생성자와 소멸자를 호출하는 비용이다. 가끔 사용하지도 않는 변수에 대해 비용이 드는 경우도 있다. std::string encryptPassword(const std::string& password) { using namespace std; string encryted; if(password.length() < MinimumPasswordLength) { throw logic_error("Password is too short"); } ... // 암호화 return encryted; } encryted 객체는 password의 길이가 짧아 예외..
문제 제한 사항을 보고 target의 범위와 개수가 많다는 것을 보고 완전 탐색은 불가능하다고 생각했다. 모든 target을 처리해야 하기 때문에 정렬한 후 그리디로 처리해도 될 것이라 판단했다. 문제 설명 A 나라가 B 나라를 침공하였습니다. B 나라의 대부분의 전략 자원은 아이기스 군사 기지에 집중되어 있기 때문에 A 나라는 B 나라의 아이기스 군사 기지에 융단폭격을 가했습니다. A 나라의 공격에 대항하여 아이기스 군사 기지에서는 무수히 쏟아지는 폭격 미사일들을 요격하려고 합니다. 이곳에는 백발백중을 자랑하는 요격 시스템이 있지만 운용 비용이 상당하기 때문에 미사일을 최소로 사용해서 모든 폭격 미사일을 요격하려 합니다. A 나라와 B 나라가 싸우고 있는 이 세계는 2차원 공간으로 이루어져 있습니다. ..
std::swap이 정의한 타입에 대해 느리게 동작할 여지가 있다면 swap을 멤버 함수로 제공해라. 이 멤버 swap은 예외를 던지지 않도록 해야 한다. 멤버 swap을 제공했다면, 이 멤버를 호출하는 비멤버 swap도 제공해라. 클래스에 대해서는 std:swap도 특수화해야 한다. 사용자 입장에서 swap을 호출할 때, std::swap에 대한 using 선언을 넣어 준 후에 네임스페이스 한정 없이 swap을 호출하라. 사용자 정의 타입에 대한 std 템플릿을 완전 특수화하는 것은 가능하다. 그러나, std에 어떤 것이라도 추가하려 하지 마라. swap 지원 & 예외 처리 swap은 예외 안전성 프로그래밍에 없어선 안되는 함수이다. 자기 대입의 가능성에 대처하기 위한 대표적인 메커니즘으로 널리 알려져..
문제 주어진 두 원 사이에 있는 정수의 점의 개수를 구하는 문제이다. 원의 방정식을 이용하여 쉽게 풀 수 있다. 제한 사항을 보면 주어지는 원의 반지름(r)이 꽤 크다. 따라서, 완전 탐색은 불가능하다고 판단했다. 문제 설명 x축과 y축으로 이루어진 2차원 직교 좌표계에 중심이 원점인 서로 다른 크기의 원이 두 개 주어집니다. 반지름을 나타내는 두 정수 r1, r2가 매개변수로 주어질 때, 두 원 사이의 공간에 x좌표와 y좌표가 모두 정수인 점의 개수를 return하도록 solution 함수를 완성해 주세요. ※ 각 원 위의 점도 포함하여 셉니다. https://school.programmers.co.kr/learn/courses/30/lessons/181187# 프로그래머스 코드 중심의 개발자 채용. ..
연속된 부분 수열의 합 오름 차순으로 정렬된 수열에서 부분 수열의 합이 k인 가장 짧고 왼쪽에 있는 부분 수열을 찾는 문제이다. 이미 정렬되어 있기 때문에 투 푸인터를 이용하면 쉽게 풀 수 있다. 문제 설명 비내림차순으로 정렬된 수열이 주어질 때, 다음 조건을 만족하는 부분 수열을 찾으려고 합니다. 기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열이어야 합니다. 부분 수열의 합은 k입니다. 합이 k인 부분 수열이 여러 개인 경우 길이가 짧은 수열을 찾습니다. 길이가 짧은 수열이 여러 개인 경우 앞쪽(시작 인덱스가 작은)에 나오는 수열을 찾습니다. 수열을 나타내는 정수 배열 sequence와 부분 수열의 합을 나타내는 정수 k가 매개변수로 주어질 때, 위 조건을 만족하는 ..
과제 진행하기 시간을 시간, 분으로 관리하면 헷갈릴 것 같아 분으로 환산한 뒤 계산했다. 그리고 모든 데이터가 string으로 들어온다. 이를 원하는 타입으로 변환하여 계산하는 부분이 번거로웠는데 여러 문제에서 이런 부분이 있다. 항상 생각했지만 regex를 공부해서 쉽게 처리하면 좋을 것 같다. (성능 문제) 현재 문제에서는 char의 ASCII값을 기준값('0'의 ASCII)을 빼는 식으로 계산했고 소요 시간의 자릿수가 고정된 것이 아니라 stoi를 사용하여 변환했다. find, substr을 사용하는 것을 추천 int det = 문자열.find('찾을 문자'); string pre = 문자열.substr(0, det); string suf = 문자열.substr(det + 1); 성능은 ASCII를..