함수오버로딩에 대하여 설명하여라

 

C++에서 함수호출 시 전달되는 인자를 통해서 호출하고자 하는 함수의 구분이 가능하기 때문에 매개변수가 다른 동일한 이름의 함수를 허용한다.

C의 경우 함수의 이름만으로, C++의 경우에는 함수의 이름과 매개변수로 함수를 구분

매개변수의 개수와, 자료형이 다른 같은 이름의 함수를 중복 정의 하는 것.

 

 

객체지향언어 vs 절차지향언어

 

절차지향언어 : 순차적 실행, 컴퓨터의 작업처리방식과 유사하여 객체지향보다 빠른 처리가능

계산중심언어, 함수가 중심이 되고, 데이터는 보조기능

 

객체지향언어 : 실제 세계를 모델링 또한 추상화, 캡슐화, 상속, 다형성의 특징

 

- 추상화 : 불필요 정보는 숨기고 중요 정보만을 표현

- 캡슐화 : 코드 재활용 목적, 캡슐화를 지켜야 상속과 다형성이 성립

- 상속 : 하나의 클래스가 가지고 있는 특징을 그대로 다른 클래스에게 물려줌

- 다형성 : 하나의 변수에 여러 종류 데이터를 대입 할 수 있는 성질

 

변수와 메모리에 대해서

 

프로그램을 실행시키면 운영체제는 우리가 실행시킨 프로그램을 위해 메모리 공간을 할당 해준다. 메모리 공간은 스택, , 데이터 영역으로 나누어 진다.

 

데이터 영역 -> 전역변수와 STATIC 변수가 할당되는 영역, 프로그램 시작과 동시 할당

되고, 프로그램이 종료 되어야 메모리에서 소멸

 

스택 영역 -> 함수 호출시 생성되는 지역변수와 매개변수가 저장되는 영역, 함수 호출시 사라짐

 

힙 영역 -> 필요에 의해 동적으로 메모리를 할당 할 때 사용

할당해야 할 메모리의 크기를 프로그램이 실행 동안 결정해야 하는 경우 유용하게

사용 되는 공간이다.

Call by Value Call by Reference에 대해 설명하여라

 

Call by Value :

우리말로하면 바로 "값에 의한 호출"이란 뜻으로, 어떤 함수를 호출할때에 전달인자로 그 데이터 값 자체를 전달하는 호출 방법이다

Swap의 예로 함수가 끝날 때 stack의 값도 날아가므로 값을 바뀌지 않음.

 

Call by Reference :

우리말로 "참조에 의한 호출"라는 뜻으로, 어떤 특정한 데이터 값이 아닌 그값에 대한 정보를 전달하는 호출방법이다. 주소(값에 대한 정보)를 매개 변수로 전달하여 swap

실제 값이 변경 된다.

 


 

깊은 복사와 얕은 복사에 대해서 설명하라

 

디폴트 복사 생성자는 멤버 대 멤버를 단순히 복사만 하므로, 문제가 된다.

포인터 멤버 변수의 경우 복사 생성된 객체의 변수의 포인터 또한 동일하기 때문.

이는 하나의 변수를 두 개의 객체가 참조하는 꼴을 만든다.

이후에 객체를 소멸할 때 문제가 발생 한다.

따라서 깊은 복사의 코드로 복사생성자를 구현을 해주어야 한다.

 

 

오버라이딩에 대해서 설명하여라.

 

오버라이딩(Overriding)이란 상위 클래스에 있는 메서드와 똑같은 메서드를 하위 클래스에서

재정의 하는 것을 말한다.

 

 

연산자 오버로딩

 

멤버함수에 의한 연산자 오버로딩 :

다항 -> pos1.operator+(pos2)와 같은 방식

단항 -> pos.operator++()와 같은 방식

 

전역함수에 의한 연산자 오버로딩 :

다항 -> operator+(pos1,pos2)와 같은 방식

단항 -> operator++(pos)와 같은 방식

전위 -> pos.operator++() // 후위 -> pos.opertator++(int)

동시 오버로딩 될 경우 멤버함수가 우선시 되어 호출.


Static

 

전역 변수에 선언된 static의 의미

: 선언된 파일 내에서만 참조를 허용하겠다는 의미

 

함수 내에 선언된 static의 의미

: 한번만 초기화되고, 지역변수와 달리 함수를 빠져나가도 소멸되지 않는다.

 

static 멤버 변수

: 클래스 변수라고도 한다. 메모리 공간에 딱 하나만 할당이 되어서 공유되는 변수.

멤버 변수 접근하듯 접근은 할 수있지만, 객체 내에 존재하는 것이 아니라, 객체 외부에 있 는 변수이다. 다만 객체에게 멤버변수처럼 접근 할 수 있는 권한을 줬을 뿐

ClassName::Val -> 와 같이도 접근 할 수 있다.(public의 경우)

 

static 멤버 함수

: 선언된 클래스의 모든 객체가 공유, public 선언시 이름을 통해 호출가능, 객체의 멤버로 존재 하는 것이 아니다.

 

의 할 것. 객체의 멤버가 아니기 때문에 함수 내에서 일반 멤버 변수의 값에 접근 하면 안됨

객체생성 이전에도 호출이 가능하기 때문에 static 멤버 변수만 접근 가능하다.

 

가상함수

 

C++ 컴파일러가 실제로 가리키는 객체의 자료형을 기준으로 하는게 아닌, 포인터 변수의 자료형을 기준으로 판단하기 때문에 실제로 가리키는 객체의 자료형에 따라 멤버 함수가 호출 되도록 해주는 장치.

 

한 개 이상의 가상함수를 포함하는 클래스에 대해서는 컴파일러가 가상 함수 테이블을 만든다.

가상함수 테이블을 keyvalue로 구성 되어있다.

keyvalue key는 호출하고자 하는 함수, value는 주소정보를 알려주는 정보이다.

무조건 가장 마지막에 오버라이딩을 한 자식 클래스의 멤버함수가 테이블에 포함 된다.

 

클래스에 가상 함수가 포함되면 가상함수 테이블이 생성되고, 이 테이블을 참조하기 때문에

실행 속도가 감소 한다. 하지만 미미 한 정도이다.

 

순수가상함수

 

함수의 선언만 있고 정의는 없는 것으로, 자식 클래스에서 반드시 재정의 해주어야 하고 뒷 부분에 =0을 덧붙여 인스턴싱 할 수 없도록 만드는 장치. 순수 가상 함수를 포함하는 클래스를 추상 클래스 라고 한다.

 

 

 

가상소멸자

 

상속을 받은 클래스의 생성과 소멸 과정을 보자. 생성자는 부모 클래스의 생성자가 먼저 불려지고, 소멸자는 자식 클래스의 소멸자가 먼저 불려지고 나서 부모 클래스의 소멸자가 불려진다. 그런데 다형성 이용을 위해 부모 클래스의 포인터로부터 자식 클래스를 호출할 때, 가상 함수로 정의되지 않은 자식 클래스의 오버라이딩된 함수를 호출하면 부모 클래스의 멤버 함수가 호출된다. 소멸자도 자식 클래스에서 오버라이딩된 함수라고 볼 수 있기 때문에 만약 부모 포인터로 객체를 삭제하면 부모 클래스의 소멸자가 호출된다.

따라서 소멸자를 가상 함수로 선언하지 않으면 이 경우 자식 클래스의 소멸자는 결코 호출되지 않는다. 가상 함수 키워드 virtual이 사용되었다면 이것은 자식 클래스에서 재정의될 수 있음을 명시하기 때문에 포인터의 종류에 상관없이 항상 자식 클래스의 메서드가 호출된다. , 자식 클래스의 소멸자가 호출되고 나서 부모 클래스의 소멸자가 호출된다.

따라서 상속 관계가 있고 소멸자에서 리소스를 해제해야 하는 경우 반드시 소멸자를 가상 함수로 선언해야 한다.

 

 

대입연산자

 

복사생성자와 마찬가지로 동적 할당으로 인해 깊은 복사가 필요 할 때 프로그래머가 구현

A a;

A b;

a = b; 와 같이 이미 생성 및 초기화가 진행된 객체를 대상으로 operator=를 호출하여

대입 하는 경우를 말한다.

 

자식클래스의 대입연산자를 정의해야 하는 상황에 놓이게 되면, 부모 클래스의 대입연산자를 명시적으로 호출해야 한다.


스마트포인터

 

똑똑한 포인터의 역할을 하는 객체

적은버그, 자동청소, 자동 초기화, 댕글링포인터 등에 대한 이점이 있다.

unique_ptr : 소유권을 독점하기 때문에 복사 생성이 안됨 그러나 이동은 가능(소유권 이전)

shared_ptr

 



 

형 변환 연산자

 

dynamic_cast

: 상속관계에 놓여 있는 두 클래스 사이에서 자식 클래스의 포인터 및 참조형 데이터를

부모클래스의 포인터 및 참조형 데이터로 형 변환 하는 경우

반대로, 다형적 변수의 경우 EX) base* a = new Sub; 의 경우

자식클래스의 포인터로 형변환 할 수 있다.

 

static_cast

: A에서 B타입으로 바꿔주는 형변환 연산자, 그러나 책임을지지(런타임 타입검사 X) 않는다.

void 포인터를 다른 타입의 포인터로 변환 가능, 상속 관계 게층 간 변환 가능

실수형과 정수형 등 기본 데이터 타입간 변환 가능.

 

const_cast

: const를 제거 하는 용도로 쓰인다.

 

reinterpret_cast

: C스타일의 캐스팅과 가장 비슷한 기능을 한다. 런타임 오류가 나는 것처럼 컴파일러가 뒷감당을 해주지 않기 때문에 최대한 사용하지 않는 것이 좋음

 

volliatile

 

외부적인 요인으로 해당 값이 언제든지 바뀔 수 있음을 뜻한다. 해당 변수에 대해서는

최적화를 수행하지 않는다.


싱글톤 패턴에 대해 설명하시오

 

하나의 인스턴스만을 생성하고 사용 할 수 있다.

 

생성자를 private으로 두고. 자기 자신을 얻는 함수를 만들어 미리 만들어 두었던

자기 자신 객체를 반환 하는 방법으로 사용.

 

프로그램 내에 단 하나만 존재해야 하는 객체가 필요 할 때 사용

 

단점 : 객체가 static으로 선언되기 때문에 싱글톤 객체를 사용하지 않더라도

일단 메모리에 올려두기에 메모리 낭비가 될 수 있다.

 

 

제네릭 프로그래밍이란 무엇인가?

 

데이터 형식에 의존하지 않고, 하나의 값이 여러 다른 데이터 타입들을 가질 수 있는

기술에 중점을 두어 재사용성을 높일 수 있는 프로그래밍 방식으로 템플릿은 STL 제네릭

프로그래밍의 핵심이다.

 

 

 

함수객체

 

함수호출연산자를 오버로딩 하여 객체가 함수처럼 동작하도록 구현 한 것

함수와 달리 객체를 사용하면 속성을 지닐 수 있는 것이 가능하고, 함수 객체가

일반적인 함수보다 ᄈᆞ르기도 하고 각각의 함수객체는 서로 다른 타입을 지닌다는 장점을 가진다.



'프로그래밍 > C++언어' 카테고리의 다른 글

환형 연결리스트  (0) 2019.02.05
#include <iostream>
#include <cstring>
using namespace std;
struct Node
{
char m_cName[20];
int m_iHp;
int m_iMp;
int m_iSpeed;
int m_iRange;
char m_cPosition[20];
Node* next;
};
//////////////////
// 함수 //
//////////////////
int Menu();
void InputData();
void Insert( char* name, int hp, int mp, int speed, int range, char* position );
void PrintAll();
void Search();
void Delete();
void PositionDeleteAll();
void FindMaxHp();
void SortByHp();
//////////////////
// 변수 //
//////////////////
Node *head = NULL;
char inputName[20];
int inputHp;
int inputMp;
int inputSpeed;
int inputRange;
char inputPosition[20];
int maxHp;
int sortFlag;
//////////////////
// 메인 //
//////////////////
int main()
{
Insert("럭스", 477, 334, 330, 550, "mid");
Insert("베이가", 492, 342, 340, 525, "mid");
Insert("벨코즈", 507, 325, 340, 525, "bottom");
Insert("징크스", 517, 245, 325, 525, "bottom");
Insert("오리아나", 517, 334, 325, 525, "mid");
Insert("트위치", 525, 287, 330, 550, "jungle");
Insert("앨리스", 529, 324, 335, 550, "jungle");
Insert("바드", 535, 350, 330, 500, "bottom");
Insert("코그모", 546, 322, 325, 500, "bottom");
Insert("룰루", 552, 292, 325, 550, "suppot");
Insert("모데카이저", 555, 120, 340, 120, "mid");
Insert("드레이븐", 557, 310, 330, 550, "bottom");
Insert("자르반4세", 571, 302, 340, 175, "jungle");
Insert("케일", 574, 322, 335, 125, "top");
Insert("블리츠크랭크", 582, 267, 325, 125, "suppot");
Insert("문도박사", 582, 0, 345, 125, "top");
Insert("다이애나", 589, 297, 345, 150, "mid");
Insert("워윅", 592, 240, 345, 125, "jungle");
Insert("잭스", 592, 288, 350, 125, "top");
Insert("트린다미어", 625, 100, 345, 125, "top");
Insert("갱플랭크", 631, 282, 345, 125, "top");
while ( 1 )
{
switch ( Menu() )
{
case 1 :
Search();
break;
case 2 :
InputData();
Insert(::inputName, ::inputHp, ::inputMp, ::inputSpeed, ::inputRange, ::inputPosition);
break;
case 3 :
Delete();
break;
case 4 :
PositionDeleteAll();
break;
case 5 :
PrintAll();
break;
case 6 :
FindMaxHp();
break;
case 7 :
SortByHp();
break;
default :
break;
}
}
}
int Menu()
{
int num;
cout << "--------------Menu---------------" << endl;
cout << "1. 챔피언 Search" << endl;
cout << "2. 챔피언 Insert" << endl;
cout << "3. 챔피언 Delete" << endl;
cout << "4. Position DeleteAll" << endl;
cout << "5. PrintAll" << endl;
cout << "6. FindMaxHp" << endl;
cout << "7. SortByHp" << endl;
cout << "----------------------------------" << endl;
cout << "메뉴를 입력하세요 [ 1 ~ 7 ] : ";
cin >> num;
if ( 0 < num && num < 8)
return num;
}
void Insert(char* name, int hp, int mp, int speed, int range, char* position)
{
Node* temp = head;
if ( temp != NULL && temp->next != head ){
while ( temp->next != head)
temp = temp->next;
temp->next = new Node;
temp = temp->next;
temp->next = head;
temp->m_iHp = hp;
temp->m_iMp = mp;
temp->m_iSpeed = speed;
temp->m_iRange = range;
strcpy(temp->m_cName, name);
strcpy(temp->m_cPosition, position);
}
else if (head == NULL){
head = new Node;
head->next = head;
head->m_iHp = hp;
head->m_iMp = mp;
head->m_iSpeed = speed;
head->m_iRange = range;
strcpy(head->m_cName, name);
strcpy(head->m_cPosition, position);
}
else if ( temp->next == temp){
temp->next = new Node;
temp->next->next = head;
temp->next->m_iHp = hp;
temp->next->m_iMp = mp;
temp->next->m_iSpeed = speed;
temp->next->m_iRange = range;
strcpy(temp->next->m_cName, name);
strcpy(temp->next->m_cPosition, position);
}
}
void PrintAll()
{
Node *temp = head;
if ( head != NULL && (
!strcmp(temp->m_cPosition, "jungle") ||
!strcmp(temp->m_cPosition, "suppot") ||
!strcmp(temp->m_cPosition, "bottom") ||
!strcmp(temp->m_cPosition, "mid") ||
!strcmp(temp->m_cPosition, "top")) ){
while (temp->next != head)
{
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
temp = temp->next;
}
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
}
void Search()
{
Node* temp = head;
char name[20] = "NULL";
cout << "검색할 챔피언의 이름을 입력해주세요 : ";
cin >> name;
while ( temp->next != head){
if ( !strcmp(name, temp->m_cName) ){
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
temp = temp->next;
}
if ( !strcmp(name, temp->m_cName) ){
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
}
void Delete()
{
Node* temp = head;
Node* p = NULL;
char name[20] = "NULL";
cout << "삭제할 챔피언의 이름을 입력해주세요 : ";
cin >> name;
while ( temp->next != head){
if ( !strcmp(name, temp->next->m_cName) ){
p = temp->next;
temp->next = temp->next->next;
p->next = nullptr;
delete p;
}
else
temp = temp->next;
}
if ( !strcmp(name, head->m_cName) ){
p = head;
p = head->next;
delete head;
head = p;
temp->next= head;
}
}
void PositionDeleteAll()
{
Node* temp = head;
Node* p = NULL;
char position[20] = "NULL";
cout << "삭제할 Position을 입력해주세요 : ";
cin >> position;
while ( temp->next != head){
if ( !strcmp(position, temp->next->m_cPosition) ){
p = temp->next;
temp->next = temp->next->next;
p->next = nullptr;
delete p;
}
else
temp = temp->next;
}
if ( !strcmp(position, head->m_cPosition) ){
p = head;
p = head->next;
delete head;
head = p;
temp->next= head;
}
};
void InputData()
{
cout << "이름을 입력하세요: ";
cin >> ::inputName;
cout << "체력을 입력하세요: ";
cin >> ::inputHp;
cout << "마력을 입력하세요: ";
cin >> ::inputMp;
cout <<"속도 입력하세요: ";
cin >> ::inputSpeed;
cout << "범위를 입력하세요: ";
cin >> ::inputRange;
cout << "포지션을 입력하세요: ";
cin >> ::inputPosition;
}
void FindMaxHp()
{
Node* temp = head;
if ( head->m_iHp > maxHp)
maxHp = head->m_iHp;
while(temp->next != head)
{
if ( temp->m_iHp > maxHp)
maxHp = temp->m_iHp;
temp = temp->next;
}
if (temp->m_iHp > maxHp)
maxHp = temp->m_iHp;
cout << "가장 높은 체력 : ";
cout << maxHp << endl;
temp = head;
if ( head->m_iHp == maxHp){
cout << "이름 : " << head->m_cName << endl;
cout << "체력 : " << head->m_iHp << endl;
cout << "마력 : " << head->m_iMp << endl;
cout << "속도 : " << head->m_iSpeed << endl;
cout << "범위 : " << head->m_iRange << endl;
cout << "포지션 : " << head->m_cPosition << endl;
}
while(temp->next != head)
{
if ( temp->m_iHp == maxHp){
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
temp = temp->next;
}
if (temp->m_iHp == maxHp){
cout << "이름 : " << temp->m_cName << endl;
cout << "체력 : " << temp->m_iHp << endl;
cout << "마력 : " << temp->m_iMp << endl;
cout << "속도 : " << temp->m_iSpeed << endl;
cout << "범위 : " << temp->m_iRange << endl;
cout << "포지션 : " << temp->m_cPosition << endl;
}
::maxHp = 0;
}
void SortByHp()
{
Node* temp = head;
Node* rotate = head;
Node* whileNode = head;
Node* remember = nullptr;
Node* prv = nullptr;
while(temp->next!= head){
if( temp->m_iHp > temp->next->m_iHp){
if ( temp == head){
if ( temp->next->next != head){
rotate = head;
while(rotate->next != head)
rotate = rotate->next;
remember = temp->next;
temp->next = temp->next->next;
remember->next = temp;
head = remember;
rotate->next = head;
temp = head;
}
else if ( temp->next->next == head){
remember = temp->next;
temp->next = temp->next->next;
remember->next = temp;
head = remember;
temp->next->next = head;
temp = head;
}
}
else if ( temp->next->next != head){
rotate = head;
while(rotate->next != temp){
rotate = rotate->next;
}
prv = rotate;
remember = temp->next;
temp->next = temp->next->next;
remember->next = temp;
prv->next = remember;
temp = head;
}
else if ( temp->next->next == head){
rotate = head;
while(rotate->next != temp){
rotate = rotate->next;
}
prv = rotate;
remember = temp->next;
temp->next = temp->next->next;
remember->next = temp;
prv->next = remember;
temp->next = head;
temp = head;
}
}
temp = temp->next;
}
sortFlag = 1;
}



















'프로그래밍 > C++언어' 카테고리의 다른 글

[ 기술면접 정리 서버 / C++ ]  (0) 2019.03.06

+ Recent posts