|
Program Lang./C++ 2016. 7. 21. 18:57
앞 장에서 pat(program associate table)을 MySQL로 저장해서 확인해 보았지만 최종적으로 webbrower에서
확인하기에는 Node.js 같은 것을 붙여야 하고 일이 커져서 일단 아래와 같이 구현해 본다.
MFC 나 C#등을 이용해서 UI를 짜면 되지만 실제 보여주는 UI는 webbrowser에서 보여지는 것을 보고 싶다.
그래서 일단 c++ native application에서 pat 정보를 parsing완료하면 json 포멧으로
저장한다. 저장 위치는 webserver root directory 이다.
저장된 값은 webbrowser를 실행하고 해당 URL을 입력해서 출력되는 것을 확인한다.
1. 선수 작업
먼저 c++ json parser and writer가 필요하다. 난 boost spirit을 이용한다.
아래 참고 사이트에서 소스를 받아서 빌드하면 잘 된다. 난 cmake만을 사용하므로 cmake로 돌리고
헤더 파일과 static library만을 내 project에 포함시키고 아래 소스 트리에서 json_spirit 폴더에 해당함. 내 project CMakeLists.txt파일에서 json_spirit 헤더와 라이블러리 패스만 잡아줌.
json_spirit 폴더 내의 CMakeLists.txt 파일은 내꺼 프로젝트와 상관없고 원래 있었던 것으로 연동안됨.
2. 소스 트리
. ├── CMakeLists.txt ├── json_spirit │ ├── CMakeFiles │ │ ├── CMakeDirectoryInformation.cmake │ │ ├── json_spirit.dir │ │ │ ├── CXX.includecache │ │ │ ├── DependInfo.cmake │ │ │ ├── build.make │ │ │ ├── cmake_clean.cmake │ │ │ ├── cmake_clean_target.cmake │ │ │ ├── depend.internal │ │ │ ├── depend.make │ │ │ ├── flags.make │ │ │ ├── json_spirit_reader.cpp.o │ │ │ ├── json_spirit_value.cpp.o │ │ │ ├── json_spirit_writer.cpp.o │ │ │ ├── link.txt │ │ │ └── progress.make │ │ └── progress.marks │ ├── CMakeLists.txt │ ├── Makefile │ ├── cmake_install.cmake │ ├── json_spirit.h │ ├── json_spirit.vcproj │ ├── json_spirit_error_position.h │ ├── json_spirit_reader.cpp │ ├── json_spirit_reader.h │ ├── json_spirit_reader_template.h │ ├── json_spirit_stream_reader.h │ ├── json_spirit_utils.h │ ├── json_spirit_value.cpp │ ├── json_spirit_value.h │ ├── json_spirit_writer.cpp │ ├── json_spirit_writer.h │ ├── json_spirit_writer_options.h │ ├── json_spirit_writer_template.h │ └── libjson_spirit.a ├── pat.cpp ├── pat.h ├── pat_json.txt ├── psi_glob.h ├── remove.sh ├── section.cpp ├── section.h ├── test.cpp
└── types.h
3. 헤더 파일
보여지지 않는 파일은 기존 pat class와 동일하고 단지 변경 사항만 여기에 보여준다.
pat정보를 json으로 저장하기 위한 함수 선언이 추가되었다.
4. 본체
pat_json.txt 파일을 apache 서버 설정 루트 디렉토르로 만들어서 저장한다.
5. 테스트 webbrowser로 결과를 확인하는 내용은 아래 post에 정리해 두었다.
http://chipmaker.tistory.com/category/Program%20Lang./javascript/
6. pat_json.txt 파일 구조 6개의 프로그램 정보가 배열 형태의 json 포멧으로 저장되어 있다. 하나의 프로그램의 형식은 pat.h에 정의한 struct 구성과 동일하다.
7. 전체 소스 (github link)
https://github.com/heesoon/mpeg/tree/master/test/pat_json
8. 참고 자료
[boost spirit json parser and writer]
http://www.codeproject.com/Articles/20027/JSON-Spirit-A-C-JSON-Parser-Generator-Implemented
Program Lang./C++ 2016. 7. 20. 19:17
이 장에서는 SDT (Service Description Table)에 대해서 알아보고, 구현 클래스를 살펴본다.
SDT는 MPEG-2 Part 2의 규격 사항은 아니다. MPEG System의 구성은 기본 골격은 MPEG에서 출발하고
세부적인 사항은 ATSC, DVB, ISDB의 형태로 나누어진다. SDT는 DVB에 해당하는 규격이고
요즘은 ATSC도 같이 보고 있지만 기존에 계속 DVB만해서 익숙한 것 위주로 구현해 본다.
SDT는 현재 방송되고 있는 방송사업자 정보나 방송 채널 이름 같은 정보를 얻어올 수 있다.
좀 세부적으로 들어가면 PAT에 있는 프로그램 갯수가 정말 정확할까? 이런 문제들이 속출하게된다.
테스트 코드에서 볼 수 있듯이 PMT를 parsing하기 위해서는 PAT가 먼저 parsing이 되어야 한다. 하지만 SDT의 경우에는 테스트 코드에서도 볼 수 있지만 PAT와 상관없이 바로 Section PID를 알고 있으므로 바로 PAT와 상관없이 Parsing할 수 있다. 여기서 복합적으로 성능을 올릴 수 있는 방법을 고민해 볼 수 있다. Chip의 특성을 잘 파악한다면 여러가지 복합적으로 생각해 볼 수 있다.
또한 SDT는 CI+와 직접적인 연관이 있다. 업체마다 구현은 다르겠지만 ...
상세하게 여기 기술하기에는 한계가 있다. 정보 유출로 걸릴까 무섭다.
1. 소스 트리
├── CMakeLists.txt
├── psi_glob.h
├── remove.sh
├── sdt.cpp
├── sdt.h
├── section.cpp
├── section.h
├── test.cpp
└── types.h
2. 헤더 파일
3. 본체
4. 테스트 소스
5. 실행 결과
CSectionSDT
current media type : FILE
mediaInPath : SGP.ts
No Data !!
0] SDT version = 1, Section = 0, service_id = 208
- EIT_schedule_flag : 0
- EIT_present_following_flag : 1
- running_status : 0x4
- free_CA_mode : 0
- service Provide Name : MediaCorp TV
- service Name : TV1_SD
1] SDT version = 1, Section = 0, service_id = 209
- EIT_schedule_flag : 0
- EIT_present_following_flag : 1
- running_status : 0x4
- free_CA_mode : 0
- service Provide Name : MediaCorp TV
- service Name : TV2_SD
2] SDT version = 1, Section = 0, service_id = 210
- EIT_schedule_flag : 0
- EIT_present_following_flag : 1
- running_status : 0x4
- free_CA_mode : 0
- service Provide Name : MediaCorp TV
- service Name : TV3_HD
3] SDT version = 1, Section = 0, service_id = 211
- EIT_schedule_flag : 0
- EIT_present_following_flag : 1
- running_status : 0x4
- free_CA_mode : 0
- service Provide Name : MediaCorp TV
- service Name : TV4_HD
4] SDT version = 1, Section = 0, service_id = 212
- EIT_schedule_flag : 0
- EIT_present_following_flag : 1
- running_status : 0x4
- free_CA_mode : 0
- service Provide Name : MediaCorp TV
- service Name : TV5_Radio
5] SDT version = 1, Section = 0, service_id = 213
- EIT_schedule_flag : 0
- EIT_present_following_flag : 1
- running_status : 0x4
- free_CA_mode : 0
- service Provide Name : MediaCorp TV
- service Name : TV6_Rad
~CSection
~SDT |
6. 전체 소스 (github link)
소스 코드는 여기 있는 부분과 다를 수 있다. 중간에 버그나 수정이 필요하면 다시 올리기 때문에 git에서 받는게 가장 최신임.
https://github.com/heesoon/mpeg/tree/master/test/sdt
Program Lang./C++ 2016. 7. 19. 22:05
이 장에서는 PMT (Program Map Table)에 대해서 알아보고, 구현 클래스를 살펴본다.
PMT의 주요목적은 ES (Element Stream)에 대한 PID를 얻어오는 것이다.
또한 각 ES의 Type을 확인할 수 있다. Type의 의미는 현재 ES가 Audio인지 아니면 Video인지
Video이면 MPEG-2, MPEG-4 Part 4, MPEG-4 Part 10 지금은 UHD를 위한 타입도 추가되었다.
Set-Top Box나 TV에서는 A/V Decoder 블록이 존재하고 PMT에서 추출한 ES에 대한
PID를 A/V Decoder에 잘 넘겨주는 것이 System Decoder단 작업의 일이라고 보면된다.
PMT PID에 PCR PID가 있는데 Adaptation Field에 존재하는 PCR PID와 어떤 상관관계가
있는지 기억이 나지 않는다.
Adaptation Field를 이용하여 PCR Recovery, Rate 등 세가지인가 만족해야 하는 조건이 있다.
전에 한번 짜봐서 확인해 봤는데 분석기와 동일한 결과가 나왔다.
기회가 되면 소스 정리해서 올려놔야겠다.
Stream Analyzer처럼 Stream Type을 보기 좋게 하기 위해서는 추가적인 작업이 많이
필요해서 그냥 hexa값으로 표시하는 정도로 마무리한다.
1. 소스 트리
.
├── CMakeLists.txt
├── pat.cpp
├── pat.h
├── pmt.cpp
├── pmt.h
├── psi_glob.h
├── remove.sh
├── section.cpp
├── section.h
├── test.cpp
└── types.h
2. 헤더 파일
PMT를 Parsing하기 위한 전제 조건은 PAT가 Parsing 완료되어야 한다. 따라서 PAT는 필수적으로
따라 다닌다고 보면 된다.
3. 클래스 본체
4. 테스트 코드
5. 실행 결과
hskim@MacBookPro/Volumes/Macintosh HD 2/share/c++/pmt $./test
CSection
pat generator called !!
PMT
current media type : FILE
mediaInPath : SGP.ts
No Data !!
1] PAT version = 1 Section = 0 program_number = 208 [PID 1031 (0x407)]
2] PAT version = 1 Section = 0 program_number = 209 [PID 1032 (0x408)]
3] PAT version = 1 Section = 0 program_number = 210 [PID 1033 (0x409)]
4] PAT version = 1 Section = 0 program_number = 211 [PID 1034 (0x40a)]
5] PAT version = 1 Section = 0 program_number = 212 [PID 1035 (0x40b)]
6] PAT version = 1 Section = 0 program_number = 213 [PID 1036 (0x40c)]
1] PMT version = 1 Section = 0 program_number = 208 [PCR PID 260 (0x104)]
-> [ 1] stream_type = 0x11 [ES PID 515 (0x203)]
-> [ 2] stream_type = 0x11 [ES PID 514 (0x202)]
-> [ 3] stream_type = 0x11 [ES PID 513 (0x201)]
-> [ 4] stream_type = 0x11 [ES PID 516 (0x204)]
-> [ 5] stream_type = 0x1b [ES PID 260 (0x104)]
-> [ 6] stream_type = 0x6 [ES PID 103 ( 0x67)]
-> [ 7] stream_type = 0x6 [ES PID 102 ( 0x66)]
-> [ 8] stream_type = 0x6 [ES PID 101 ( 0x65)]
-> [ 9] stream_type = 0x6 [ES PID 100 ( 0x64)]
2] PMT version = 1 Section = 0 program_number = 209 [PCR PID 259 (0x103)]
-> [ 1] stream_type = 0x11 [ES PID 517 (0x205)]
-> [ 2] stream_type = 0x11 [ES PID 513 (0x201)]
-> [ 3] stream_type = 0x11 [ES PID 516 (0x204)]
-> [ 4] stream_type = 0x1b [ES PID 259 (0x103)]
3] PMT version = 1 Section = 0 program_number = 210 [PCR PID 257 (0x101)]
-> [ 1] stream_type = 0x11 [ES PID 513 (0x201)]
-> [ 2] stream_type = 0x6 [ES PID 100 ( 0x64)]
-> [ 3] stream_type = 0x11 [ES PID 516 (0x204)]
-> [ 4] stream_type = 0x1b [ES PID 257 (0x101)]
4] PMT version = 1 Section = 0 program_number = 211 [PCR PID 258 (0x102)]
-> [ 1] stream_type = 0x11 [ES PID 514 (0x202)]
-> [ 2] stream_type = 0x11 [ES PID 517 (0x205)]
-> [ 3] stream_type = 0x6 [ES PID 102 ( 0x66)]
-> [ 4] stream_type = 0x11 [ES PID 514 (0x202)]
-> [ 5] stream_type = 0x1b [ES PID 258 (0x102)]
5] PMT version = 1 Section = 0 program_number = 212 [PCR PID 514 (0x202)]
-> [ 1] stream_type = 0x11 [ES PID 516 (0x204)]
-> [ 2] stream_type = 0x11 [ES PID 514 (0x202)]
6] PMT version = 1 Section = 0 program_number = 213 [PCR PID 516 (0x204)]
-> [ 1] stream_type = 0x11 [ES PID 516 (0x204)]
~CSection
pat destroy called !!
~PMT |
6. 전체 소스 (github link)
https://github.com/heesoon/mpeg/tree/master/test/pmt
Program Lang./C++ 2016. 7. 19. 21:11
http://chipmaker.tistory.com/entry/mysql-cpp-connector-study
에서 cpp connector wrapper 클래스를 만들고 이 클래스를 기반 클래스로 정의하였다.
여기서는 이 기반 클래스를 구체화하는 예제로 PAT 정보를 MySQL에 써 보도록 하자.
1. 소스 트리
. ├── CMakeLists.txt ├── mysqlAdaptor.cpp ├── mysqlAdaptor.h ├── mysqlAdaptorForPAT.cpp ├── mysqlAdaptorForPAT.h ├── pat.cpp ├── pat.h ├── psi_glob.h ├── remove.sh ├── section.cpp ├── section.h ├── test.cpp
└── types.h
2. 헤더 파일
PAT 정보를 MySQL에 쓰는 파일만 보고 전체 파일을 github link을 참조.
3. 클래스 본체
기반 클래스에서 순수 가상함수를 사용하였으나, 구지 순수 가상함수를 만들지 않고
가상함수로 만들고 함수 오버라이딩 기법을 사용해도 되지만 두서 없이 c++ 공부하다 보니 그 떄 생각나고
짜보고 싶은 것을 위주로 생각해서 진행해서 어떤 설계를 기반으로 하지 않은점은 고력해야 한다.
4. 테스트 예제
5. 실행 결과
6. github link (전체 소스)
https://github.com/heesoon/mpeg/tree/master/test/patSaveToMySQLDB
Program Lang./C++ 2016. 7. 14. 20:44
앞 단원 mpeg section parser에서 넘겨주는 section information을 기반으로
PID가 '0'에 해당하는 PAT를 분석하여 필요한 데이터를 저장하는 PAT class를 설계하고 구현한다.
PAT(Program Associate Table)은 셋탑박스나 TV단에서 채널 수신 중, 가장 처음에 수신해서 Parsing해야 한다.
대기업 TV 제조사나 이름있는 셋탑박스 업체는 채널 전환 시에도 모든 mpeg system을 수신하고 기존 값과
비교해서 변경 사항이 있으면 조치를 취하지만 중국 제품은 네가 10년 전에 셋탑박스 개발 시에는 처음 설치시에
Scan 후에 다시는 하지 않는 구조였다.
PAT에서는 program number (service ID라고도 한다)와 PMT PID을 저장하고 있다.
현재 목적은 구현이기 때문에 자세한 설명은 규격서을 참조하면 알 수 있다.
1. 소스 트리
일단 기존 section class 파일들은 전에 기술한 내용과 동일한 부분이다. 변경 추가 사항인 PAT을 살펴본다.
.
├── CMakeLists.txt
├── pat.cpp
├── pat.h
├── psi_glob.h
├── remove.sh
├── section.cpp
├── section.h
├── test.cpp
└── types.h
2. PAT class header
3. PAT class
PAT에 존재하는 program number와 PMT PID를 갯수 만큼 파싱해서 forward list에 저장한다.
동일한 값을 저장하는 것을 피하기 위해서 버전과 section number가 동일하면 리스트 추가하지 않는다.
HW적인 chip상에서는 여기서 구현한 것처럼 section number를 구분하지 않는다.
section number와 last section number를 확인하고 last section number까지 수신이 완료되면
PAT에 대한 section이 모두 완료되고 상위 레이어에 올려준다.
PAT section은 max section 길이가 1024 바이트로 기억된다.
여기서는 HW기반과 다르게 section 하나 하나를 분석하기 위해서 section number까지 고려한다.
보통 section에서 version number는 중요하다. version이 바뀌면 기존에 저장되어 있는 PAT와
TV가 동작 중이라면 현재 수신 중인 채널에 대한 처리가 고려되어야 한다.
일반적으로 처음 PAT를 수신 후에 version 변경여부를 일정 시간 타이머로 확인하는 작업도 있다.
4. main함수
5. 전체 소스 (github 위치)
https://github.com/heesoon/mpeg/tree/master/test/pat
Program Lang./C++ 2016. 7. 13. 22:18
MPEG-2 Part 1, Analyzer를 c++ 공부 차원에서 한번 만들어 보기로 하자.
첫번째 클래스는 ts파일에서 188 바이트씩 읽어와서 section을 넘겨주는 section parser이다.
완전 단순하게 adaptation field을 보고 PID와 PID에 해당하는 section을 단순히 넘기는 클래스이다.
다음에 이어질 PSI (PAT, PMT, SDT ...)에서 사용하기 위함.
사실 셋탑박스나 TV단에서는 system decoder 블록이 별도로 존재하고 chip 자체적으로
PID만 주면 해당 PID에 대한 첫번째 section부터 마지막 setion까지 수신 후,
callback function으로 section을 return해 준다. 기본 길이는 1024 ~ 4096 Byte이다.
이 동작은 네가 경험한 chip에서는 모두 동작이 동일하다.
블로그에 올릴 떄는 현재 기준으로 파일만 대응했는데, IP에서도 가능하도록 도전해 볼 생각이다.
1 소스트리
.
├── CMakeLists.txt
├── SGP.ts
├── psi_glob.h
├── remove.sh
├── section.cpp
├── section.h
├── test.cpp
└── types.h
2. section class header
3. section class
4. test을 위한 main
test는 단순하다. 단순하게 파일해서 188Byte씩 읽어 들이고 setion이라는 구조를 선언하고 이 구조체에
현재 ts에 대한 pid값과 ts header를 제거한 부분을 구조체 버퍼에 넣어서 올려준다.
5. 전체 소스 (github 아래 링크에 존재)
https://github.com/heesoon/mpeg/tree/master/test/section
Program Lang./C++ 2016. 7. 12. 15:33
기존의 예제들은 완전한 예제가 아닌 것으로 보인다.
C++ boost message queue는 POSIX 기반의 message queue를 지원하지 않는다고 한다.
또한 message queue로 메세지를 전달 시에 기본 데이터 타입이 아닌 경우에는 Serialization의 과정이 필요하다고 한다
완전한 예제인지는 모르겠지만 기존 예제를 boost에 가장 근접하게 수정을 해 보았다.
따라서 기존 예제는 좀 억지스러운 면이 있는 것 같지만 사용환경에 따라서 사용 가능할 것으로 보인다.
메세지 큐는 Inter-process보다는 Intra-process에서 자사 제품에서는 많이 사용되고 있다.
1. 소스트리
.
├── CMakeLists.txt
├── remove.sh
└── test.cpp
2. 구현 예제
Intra-process 기반으로 작성을 해 보았다. Inter-process에서 사용할지 의문이다.
3. 실행 결과
hskim@hskim-VirtualBox:~/share/prj/c++/test1-2$ ./test In main thread serialize, 37 serialize, 37 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 serialize, 37 serialize, 37 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 serialize, 37 name : heesoon.kim, age : 41 serialize, 37 name : heesoon.kim, age : 41 |
4. 전체 소스 코드
serialization.zip
https://github.com/heesoon/mpeg/tree/master/test/messageQueueWithSerialization
Program Lang./C++ 2016. 7. 11. 08:39
네가 만든 message queue를 boost library로 바꿔봤다.
boost 예제를 조금 수정했는데, boost는 process 대상이고 난 thread로 변경했을 뿐이다.
동작은 네가 만든 것과 동일하다. 단지 message queue 상태 검사는 없다.
1. 소스트리
.
├── CMakeLists.txt
├── remove.sh
└── test.cpp
2. CMakeLists.txt 변경 사항.
cmake에서 기본적으로 관리하는 package에서 찾아서 링크 시켰다.
참고로 pkg-config를 쓰려면 pkg-config를 먼저 include하고 쓰면 된다.
아직 네가 잘 못해서 Mac에서는 find_package가 먹지 않는다.
3. 테스트 소스
Program Lang./C++ 2016. 7. 8. 15:06
boost library interprocess에 message queue가 구현되어 있으나, 공부하는 차원에서 한번 만들어봤다.
소스가 너무 커서 일단 전체 소스는 zip파일 참조
1. 소스트리
.
├── CMakeLists.txt
├── messageQueue.cpp
├── messageQueue.h
├── remove.sh
├── test.cpp
└── types.h
2. message queue header 파일
3. 테스트
네가 만든 메세지 큐를 사용하는 방식은 아래와 같다.
1) 일단 메세지 큐를 연다. (Non Block 의 경우는 Non block open 함수로 연다)
2) 메세지를 보내는 task를 하나 만들고 메세지를 보낸다.
3) 메세지를 받는 task를 하나 만들고 메세지를 받는다.
main 함수도 하나의 task이므로 모든 메세지가 주고 받을 때까지 기다리다가
끝내려면 'x'를 눌러서 나간다.
thread 생성 후에 join을 하기보다는 detach로 작성한 이유는 메세지를 보내고
받는 쪽에서 처리가 안되면 계속 메세지 큐는 보내는 쪽에서 Blocking 상태임으로
모두 detach 시킨다.
이 경우 main 함수를 끝내면 안된다.
네가 구현한 메세지 큐는 메세지 큐 상태를 출력하는데 보내는 thread와 받는 thread의
ID와 현재 주고 받는 메세지 큐 상태를 check할 수 있다.
4. 실행 결과
받는 쪽 thread에서 현재 메세지 큐 상태를 확인하기 위해서 계속 출력하도록 해 봤다
~~~~~~~~~~~~ 중략 ~~~~~~~~~~~~~~~~~~~~~~
name : heesoon.kim, age : 41
--------------------------------------------------
index : 0
id : 3
msgQueueName : /mq_test
senderId : 3074534208
receiverId : 3066141504
sendMessageCount : 8
receivedMessageCount : 8
-------------------------------------------------
name : heesoon.kim, age : 41
--------------------------------------------------
index : 0
id : 3
msgQueueName : /mq_test
senderId : 3074534208
receiverId : 3066141504
sendMessageCount : 8
receivedMessageCount : 9
-------------------------------------------------
name : heesoon.kim, age : 41
--------------------------------------------------
index : 0
id : 3
msgQueueName : /mq_test
senderId : 3074534208
receiverId : 3066141504
sendMessageCount : 10
receivedMessageCount : 10
-------------------------------------------------
x
called ~messageQueue
|
5. 소스 전체
messageQueueTest.zip
Program Lang./C++ 2016. 7. 7. 10:30
템플릿 기반의 기반 클래스에서 자식 클래스를 상속 받는 경우에 대해서 정리
1. 소스 트리 . ├── CMakeLists.txt ├── test.cpp ├── test.h
2. 기반 클래스
템플릿 기반의 기반 클래스는 test.h 파일에 선언 및 정의되어 있다. printContents는 순수 가상함수로 선언하여서 자식 클래스의 데이터 타입에 맞게 구현하도록 했다.
3. 템플릿 기반의 기반 클래스에서 자식 클래스 상속
임의의 타입 T를 자식 클래스에서 계속 계승할 경우에 선언과 정의는 모두 헤더 파일(test.h)에 존재하고 아래와 같은 형식을 갖는다. 즉 template <typename T>가 계속 따라 다닌다.
새로운 템플릿 기반 자식 클래스가 생성되었다. 다만 mA는 기반 클래스에서 상속 받았으므로 자식 클래스에서 기반 클래스 데이터를 초기화하는 부분과 신규로 추가한 get() 함수에 대해서 구현 방식에 주의하면 된다.
4. 템플릿 기반 기반 클래스에서 상속을 받되 특정 타입을 고정해서 받는 경우
문법적으로 정확히 맞는지는 모르겠지만 문제는 없어 보인다. 템플릿의 특수화와 조금 유사하지만 상속까지 더해져서 기본 템플릿 특수화와의 차이점 구분이 필요.
상속을 받지만 특수화가 되었다는 측면에서 클래스의 맴버함수 정의는 구현 파일로 옮겨도 될 것 같다. 일단 임의의 타입으로 하나의 구조체를 선언하고 이 구조체만을 위한 자식 클래스를 기반 클래스에 타입으로 주고 상속을 받았다. 이런 경우를 머라 불러야 하는지?
5. 테스트
6. 상속에 의한 특수화가 아닌 템블릿 중에 하나의 타입에 대한 Specialization 예제
person 타입을 기반클래스에서 주고 자식 클래스에서 이를 상속 받는 개념은 위의 예제에서 봤다. 사실 이게 맞는 것인지는 모르겠다. 이 부분은 표준 라이브러리 예제를 찾아봐야겠다.
원래 c++ 문법에서 나오는 특정 타입으로 특수화를 위한 코드로 변경하면 아래와 같다.
개인적으로 위의 코드가 더 이상해 보인다. 템플릿에 기존 데이터랑 함수가 다 정의되어 있는데 특정 타입을 위한 클래스를 반복적으로 정의하는 것은 차라리 기반 클래스에서 특정 타입만 상속해서 사용하는 것이 더 맞는 것 아닌가?
테스트 코드
|