티스토리 뷰
반응형
추가되는 기능
- 정의된 class의 기능을 재정의하거나 확장하고자 할 때 해당 class를 상속할 수 있다.
- 상속받은 class(이하 'Derived')는 상속되는 class(이하 'Base')의 모든 기능을 포함하고 있다.
#include <iostream> class Base { private: int value; public: int get() const { return value; } void set(int value) { this->value = value; } }; class Derived : public Base {}; // ^^^^^^ ^^^^ int main() { Derived d; d.set(10); std::cout << d.get() << std::endl; return 0; }
Derived는 Base의 기능을 부분적으로 재정의(override)할 수 있다.
class Derived : public Base { private: int d_value; public: void set_d(int d_value) { this->d_value = d_value; } int get() const { return Base::get() * d_value; } }; int main() { Derived d; d.set(10); d.set_d(2); std::cout << d.get() << std::endl; return 0; }
- Derived는 Base이지만, Base는 Derived가 아니다.
Derived d1; d1.set(10); Base b1 = d1; // OK std::cout << b1.get() << std::endl; Base b2; Derived d2 = b2; // Error
하위 class에서 상위 class로의 up-casting은 데이터 유실을 일으킬 수 있고, 상위 class에서 하위 class로의 down-casting은 없는 값을 만들어낼 수 없기에 불가능하다. - 접근 지정자 protected로 선언된 멤버 변수, 함수는 하위 class에서만 호출될 수 있다. 이때, this 기호를 사용하여 호출해야한다.
class Base { protected: int value; public: int get() const { return value; } void set(int value) { this->value = value; } }; class Derived : public Base { public: int get() const { return this->value * 2; } }; class FarFarAway : public Derived { public: int get() const { return this->value; } }; int main() { FarFarAway f; f.set(10); Derived d = f; std::cout << d.get() << std::endl; std::cout << f.get() << std::endl; return 0; }
- Base가 template class인 경우, template parameter를 만족시켜야한다.
template<typename T> class Base { protected: T value; public: T get() const { return value; } void set(T value) { this->value = value; } }; template<typename T = int> class Derived : public Base<T> { public: T get() const { return this->value * 2; } }; class FarFarAway : public Derived<long> { public: long get() const { return this->value; } }; int main() { FarFarAway f; f.set(10); Derived d = f; std::cout << d.get() << std::endl; std::cout << f.get() << std::endl; return 0; }
목표
- vector를 상속받는 class char_seq를 정의한다.
char_seq는 char형의 배열을 갖는 자료구조로, 출력시 배열의 꼴이 아닌 문자열의 꼴로 출력한다.
디자인
- char_seq: 다음 class를 추가한다.
template<int INITIAL_SIZE = 10> class char_seq : public vector<char, INITIAL_SIZE> - char_seq: 다음 멤버 함수가 override된다.
void print() const - vector: 다음 멤버 함수를 추가한다.
protected: T* get_data() const
멤버 변수 data를 반환한다.
구현
#include <iostream>
#include <algorithm>
template<typename T, int INITIAL_SIZE = 10>
class vector {
private:
T* data;
int capacity;
int length;
bool ensure_capacity(int to_add) const {
return length + to_add < capacity;
}
void increase_capacity() {
auto tmp = data;
data = new T[capacity * 2];
std::copy(tmp, tmp + length, data);
delete[] tmp;
capacity *= 2;
}
void shiftLeft(int offset, int width) {
int tail_length = length - offset - width;
auto tail = new T[tail_length];
std::copy(data + offset + width, data + length, tail);
std::copy(tail, tail + tail_length, data + offset);
delete[] tail;
}
void shiftRight(int offset, int width) {
int tail_length = length - offset;
auto tail = new T[tail_length];
std::copy(data + offset, data + length, tail);
std::copy(tail, tail + tail_length, data + offset + width);
delete[] tail;
}
protected:
T* get_data() const {
return data;
}
public:
vector() {
data = new T[INITIAL_SIZE];
capacity = INITIAL_SIZE;
length = 0;
}
vector(const vector& v) {
data = new T[v.capacity];
capacity = v.capacity;
length = v.length;
std::copy(v.data, v.data + v.length, data);
}
~vector() {
delete[] data;
}
void add(T element) {
if (!ensure_capacity(1))
increase_capacity();
*(data + length++) = element;
}
void add(int index, T element) {
if (!ensure_capacity(1))
increase_capacity();
shiftRight(index, 1);
*(data + index) = element;
length++;
}
T get(int index) const {
return *(data + index);
}
T set(int index, T element) {
auto tmp = *(data + index);
*(data + index) = element;
return tmp;
}
T remove(int index) {
auto tmp = *(data + index);
shiftLeft(index, 1);
length--;
return tmp;
}
void print() const {
std::cout << '{';
for (int i = 0; i < length; i++)
std::cout << *(data + i) << ((i < length - 1) ? ", " : "");
std::cout << '}' << std::endl;
}
vector& operator=(const vector& v) {
data = new T[v.capacity];
capacity = v.capacity;
length = v.length;
std::copy(v.data, v.data + capacity, data);
return *this;
}
vector& operator+=(T element) {
add(element);
return *this;
}
T& operator[](int index) {
return *(data + index);
}
T operator[](int index) const {
return *(data + index);
}
};
template<int INITIAL_SIZE = 10>
class char_seq : public vector<char, INITIAL_SIZE> {
public:
void print() const {
std::cout << this->get_data() << std::endl;
}
};
int main() {
vector<char> v;
v.add('H');
v.add('e');
v.add('l');
v.add('l');
v.add('o');
v.print();
char_seq seq;
seq.add('H');
seq.add('e');
seq.add('l');
seq.add('l');
seq.add('o');
seq.print();
return 0;
}
{H, e, l, l, o} Hello
반응형
'C++ > C to C++' 카테고리의 다른 글
[C to C++] 상속 - 순수 가상함수, 추상 클래스 (0) | 2019.02.03 |
---|---|
[C to C++] 상속 - 생존주기, 가상함수 (0) | 2019.02.02 |
[C to C++] 템플릿 (0) | 2019.02.01 |
[C to C++] friend, 연산자 오버로딩 (0) | 2019.01.31 |
[C to C++] 함수 오버로딩 (0) | 2019.01.31 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- rule_of_five
- linaro
- C++ 업캐스팅
- C
- cyanogenmod
- c++ struct
- g2 korea
- LG
- C++
- G2
- vector
- rule_of_three
- dokdo-project
- CM10.2
- c++11
- Kotlin
- c++ 상속
- 객체지향
- nodeal
- dokdo project
- inline class
- f320s
- PipelineContext
- d802
- 포인터
- OOP
- Java
- dokdo 4.0.3
- CM11
- f320k
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함