목록C++ (102)
음악, 삶, 개발
일러스트레이터에서는 하나의 요소를 Layer 라고하지만, Juce 에서는 Component 라고 한다. 하나의 Component 에는 멤버 변수로 여러 Component 들이 포함될수있다. 아래와 같이 만든다. class Panel : public juce::Component { public : Panel(const juce::Colour& newColor) : color(newColor) {} void paint(juce::Graphics& g) override { g.fillAll(color); } private : const juce::Colour color; };

앞서 이론을 배웠으니, 실제 ValueTree 에 요소들을 추가, 삭제하는등에 대해 연습문제를 풀면서 해보겠다. 문제 정답 juce::Identifier treeName {"Note"}; juce::ValueTree tree {treeName}; 설명 setProperty 와 헷깔리지말자. setProperty 는 말그대로 이미 생성된 ValueTree 에 Property 를 추가 또는 변경하는것이다. ValueTree 의 이름은 반드시 초기화할때 인자로 넘겨야한다. 또한 초기화후 해당 ValueTree 의 이름은 절대 변경될수없다. 문제 정답 const juce:..

Tutorial: The ValueTree class ValueTree Class Reference ValueTree::Listener Class Reference Identifier Class Reference var Class Reference XmlElement Class Reference 이 기본기 포스트는, Tutorial: The ValueTree class 를 바탕으로 쓰여졌다. 따라서 내 포스팅을 다 읽고도, 또는 시간이 흘러 무언가 희미하다면.. 반드시 위의 Juce 공식 튜토리얼을 읽고 이 포스팅을 다시 읽도록한다. ValueTree 는 Juce 에서 제공하는 컨테이너이다. Thread 안정성을 보장하지 않기때문에..
오름차순으로 std::sort() 를 사용하기위해서는 operator< r가 오버로딩 되어야한다. bool operator< (const Note& other) const { return getStart() < other.getStart(); } 이때 이 operator< 함수뒤에 const 를 반드시 반드시 붙여야한다. 그렇지않으면 함수를 호출할때 error 가 날것이다. 이 const 가 필요한 이유는 너무도 당연하다. 우리는 < 로 두 객체를 비교하는것이지, 객체의 상태를 변화시키는것이 아니기때문이다.
C++ 에서 Move 의 의미는 이삿짐 센터라고 외우자. 현실 세계에서 이사는 한 집의 짐을 다른 집으로 다 옮기는것이지만, C++ 에서는, 한 집에서의 모든 값을 다른 집에 복사해주고, 복사를 마치면 남의 집의 값을 각 type 이 제공하는 방법으로 초기화하는것이다. 예를 들어 완전히 이해해보자. T 라는 우리가 만든 클래스가 있다. strcut T { int a; double b; float c; } 이 클래스 유형을 가진 두개의 객체 A, B 가 있고 A 를 B 로 Move 한다고 가정해보자. 이때 발생하는 실제 프로세스는 아래와 같다. 1. 객체 A 의 모든 멤버 a, b, c 의 값을, 객체 B 의 멤버 a, b, c, 의..
코멘트를 읽어보세요. 아래의 문법을 외워야한다. int main () { std::vector vec {1, 2, 3, 4}; for (auto i : vec) {} // 객체를 읽으려할때 (복사) for (const auto& i : vec) {} // 객체를 읽으려할때 (const 참조) for (auto& i : vec) {} // 객체를 수정하려할때 (참조) return 0; } rante for loop 안에 변수를 iterator 라고 생각하는 사람이 있는데, 그렇지않고 객체다. (내부적으로 iterator 를 사용하고있는 문법일뿐) const 나 & 를 붙여줌에 따라, 참조인지 복사인지가 구별된다. 위와 같이 int 가 아닌, 나의 클래스를 ranged for loop 하고자할때는 나의 클래..
일종의 포인터라서 값을 얻기위해서는 Dereference, 즉 * 를 사용하여 역참조해야한다. 아래의 코드를 보자. int main () { std::vector vec {1, 2, 3, 4}; std::cout
무조건 sizeof() 함수를 사용하여 크기를 찍어보아야한다. Peter 말에 의하면, 128 bits 이상이면 reference 로, 이하면 value 로 return 하는게 일반적이라고한다. 예를 들어보자. double 은 8 byte 즉, 64 bits 이다. (1 byte 당 8 bits) 이럴때는 그냥 value 를 return 하자. double getDouble() const {} get 함수는 무언가를 수정할 의도가 없으니, 항상 뒤에 const 를 붙이자. const 가 붙은 함수는, non-const 객체가 호출할수없다. 아래의 경우를 보자. const juce::Range& getRange() const {} juce::Range 타입은 두개의 double 로 이루어져 128 bits..
이 2가지를 외우자. erase : vector 의 요소를 삭제한다. remove : vector 의 요소를 이동시킬뿐. (= Move assignment 를 호출한다), 요소를 삭제하지않는다. 따라서 이 2가지가 적절히 섞여야한다. 아래의 코드를 암기하여 사용하도록 한다. int main() { std::vector vec {1, 2, 3, 4}; // remove a element by index vec.erase(vec.begin() + 1); // remove elements between the index vec.erase(vec.begin(), vec.end() - 1); // remove elements by value vec.erase(std::remove(vec.begin(), vec.e..
vector 가 가지고있을 클래스의 크기를 고려해야한다. 이 클래스가 매우 거대하다면, 1개를 지우려고하면, 다른 요소들을 하나씩 좌측으로 옮기기위해 수많은 Move Assignment 함수를 호출해버리는 erase() 같은 함수는, 나의 프로그램의 큰 성능 저하를 가져올수있기때문이다. 이에 대해 Peter 와 대화를 나누었고 아래와 같은 대답을 하였다. When a class is 128 bits or less, it’s cheaper to pass by value than reference is the guideline I’ve heard. The smaller something is, the cheaper it is to do operations on it (usually). ..