'언어 > CPP(cpp)' 카테고리의 다른 글
[c++] pair(페어) 사용법 [pair란][pair사용법][pair 세개 이상 사용법][pair를 stack, queue에 응용] (0) | 2019.02.09 |
---|---|
c++무한대표현하기.무한값 표현하기 (0) | 2018.11.04 |
템플릿 (0) | 2018.02.06 |
오버라이딩 (0) | 2018.02.06 |
상속 (0) | 2018.02.06 |
[c++] pair(페어) 사용법 [pair란][pair사용법][pair 세개 이상 사용법][pair를 stack, queue에 응용] (0) | 2019.02.09 |
---|---|
c++무한대표현하기.무한값 표현하기 (0) | 2018.11.04 |
템플릿 (0) | 2018.02.06 |
오버라이딩 (0) | 2018.02.06 |
상속 (0) | 2018.02.06 |
한번에 두개의 자료형을 갖는 클래스.
사용자가 직접 지정.
그냥 클래스를 만들때 사용하기도 하지만 스택, 큐 등에 유용하게 사용
1.헤더파일 #include <uitiliy>
2.생성하기위해 pair<자료형1,자료형2> 클래스명(자료형1변수,자료형2변수)
3.첫번째 자료형을 보기 위해서는 클래스명.first, 두번째 자료형을 보기 위해서는 클래스명.second이다.
4.변수를 보기 위해서는 두가지 방법이 있다.
첫번째는 클래스명.first=새로운 변수, 클래스명.second=새로운 변수
두번째는 클래스명 = make_pair(첫번째 변수, 두번째 변수)이다.
#include <iostream>
//pair를 사용하기 위해서는 <utility>헤더파일 필요
#include <utility>
using namespace std;
int main()
{
//1.생성과 동시에 초기화
pair<int, char> x(15, 'a');
cout << x.first<<endl;
cout << x.second<<endl;
//2\. x.first, x.second에 직접 담아주기
x.first = 16;
x.second = 'b';
cout << x.first << endl;
cout << x.second << endl;
//3.make_pair(int,char)로 초기화
x = make_pair(17, 'c');
cout << x.first << endl;
cout << x.second << endl;
return 0;
}
다음과 같이 하면 된다.
pair<pair<int, int>, int> ppp;
ppp.first.first = 1;
ppp.first.second = 2;
ppp.second = 3;
cout << ppp.first.first << endl << ppp.first.second <<endl<< ppp.second;
queue<pair<int, int>> q;
q.push(make_pair(33, 32));
cout << q.front().first << endl << q.front().second<<endl;
stack<pair<int, char>> s;
s.push(make_pair(31, 'a'));
cout << s.top().first << endl << s.top().second;
c++ 벡터,큐,스택 정리 (비교) (0) | 2019.02.09 |
---|---|
c++무한대표현하기.무한값 표현하기 (0) | 2018.11.04 |
템플릿 (0) | 2018.02.06 |
오버라이딩 (0) | 2018.02.06 |
상속 (0) | 2018.02.06 |
// ConsoleApplication1.cpp: 콘솔 응용 프로그램의 진입점을 정의합니다.
//
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <limits>
using namespace std;
int main()
{
int val1;
val1 = numeric_limits<int>::max();
cout << val1;
}
c++ 벡터,큐,스택 정리 (비교) (0) | 2019.02.09 |
---|---|
[c++] pair(페어) 사용법 [pair란][pair사용법][pair 세개 이상 사용법][pair를 stack, queue에 응용] (0) | 2019.02.09 |
템플릿 (0) | 2018.02.06 |
오버라이딩 (0) | 2018.02.06 |
상속 (0) | 2018.02.06 |
함수나 클래스에서 사용되는 변수가 다른함수나 클래스를 정의할때 변수의 type이 바뀌는 경우 template 클래스로 정의한다. 그리고 사용 되는 변수에 맞게 객체를 선언시 컴파일러가 알아서 해당하는 함수나 클래스를 생성하여준다.
달라지는 부분은 총 네가지이다.
1.클래스 선언 앞부분.
2.함수 선언 앞부분.
3.함수 scope 부분.
4.변수 선언부
->모든 함수, 클래스 앞부분은 template<class T>를 써주자.
ex)
헤더파일 ```
#pragma once template
1.클래스 선언 앞부분에 템플레이트 정의삽입! class CPair { public: void Setm1(T ma);
T Getm1() const; CPair(T ma);
private: T m1; };
>cpp 파일
#include "stdafx.h"
#include "CPair.h" template
} template
>main문
#include "stdafx.h"
#include "CPair.h";
#include "CPair.cpp"
#include
#include
int main() { CPair
# 템플릿 함수
달라지는 부분은 총 세가지이다.
1.함수선언 앞부분
2.변수선언부
3.함수 정의 앞부분.
ex) template
int main() { //char a = 'a', b = 'b';
int a = 3, b = 4;
cout << "a=" << a << "b=" << b<<endl;
swapValues(a, b);
cout << "a=" << a << "b=" << b<<endl;
char c = 'c', d = 'd';
cout << "c=" << c << "d=" << d << endl;
swapValues(c, d);
cout << "c=" << c << "d=" << d<<endl<<endl;
return 0;
}
template
```
[c++] pair(페어) 사용법 [pair란][pair사용법][pair 세개 이상 사용법][pair를 stack, queue에 응용] (0) | 2019.02.09 |
---|---|
c++무한대표현하기.무한값 표현하기 (0) | 2018.11.04 |
오버라이딩 (0) | 2018.02.06 |
상속 (0) | 2018.02.06 |
동적배열과 이차원 동적배열 (0) | 2018.02.06 |
부모의 함수를 자식클래스가 재정의 할 수 있게 해준다.
virtual함수. 즉 가상함수를 이용하여 처리하여준다.
가상함수는 컴파일 중에 함수를 결정하지 않고 runtime 중에 결정한다.
그함수를 부르는 객체의 모습이 아닌 실제 속 모습을 보고 결정한다.
즉 부모 클래스에서 virtual로 선언된것은 부모 객체에서는 virtual 함수가 불려지고 자식 객체에서는 자식 클래스의 함수가 불려진다.
부모의 객체에서만 virtual 함수를 만들게 되면 자동적으로 자식에게도 가상함수가 생기지만 virtual 을 붙여주어 가상함수임을 표기해준다.
순수 가상함수는 부모함수에서 가상 함수의 선언만 있고 정의가 없는것으로 자식 클래스에서 반드시 재정의해 주어야한다.
순수 가상함수를 포함한 클래스는 추상클래스로 지정되며 인스턴스를 만들 수 없다.
가상함수를 상속받아 오버라이딩해준 자식 클래스가 인스턴스를 생성할 수 있다.
특히 소멸자에서는 virtual을 붙여준다.
가상함수 예제
부모포인터 = &부모객체;
부모포인터->함수();
부모포인터 = &자식객체
부모포인터->함수(); -->자식 객체가 출력되어버리니 virtual이 필요!
(부모=자식으로 사용시 문제는 없다.)
부모 헤더파일 ```
#pragma once
namespace Figure {
class CFigure
{
public:
CFigure();
CFigure(double nX, double nY, double nAngle);
virtual ~CFigure();
virtual void Draw();
private:
double m_nX;
double m_nY;
double m_nAngle;
};
}
>부모 cpp파일
#include
CFigure::~CFigure()
{
}
void CFigure::Draw()
{
cout << "Hi! I'm just figure class!" << endl;
}
void CFigure::Centering()
{
Draw();//부모의 draw가아닌 자식의 draw가 불러진다. 그이유는 draw가 overidden되었기 때문이다.
>자식 1 헤더파일
#pragma once
#include "CFigure.h"
class COval :
public CFigure
{
public:
COval();
virtual ~COval();
virtual void Draw() ;
};
>자식 1 cpp 파일
COval::COval() :CFigure(), m_nXWidth(10), m_nYWidth(10)
{
}
COval::~COval()
{
}
void COval::Draw()
{
cout << "hi am oval!" ;
}
>자식 2 헤더파일
class CRectangle :
public CFigure
{
public:
CRectangle();
virtual ~CRectangle();
virtual void Draw();
};
>자식 3 cpp 파일
CRectangle::CRectangle()
{
}
CRectangle::~CRectangle()
{
}
void CRectangle::Draw()
{
cout << "hi i am rectangle"<<endl;
}
# 다중상속
#include
using namespace std;
class 부모1 { public: void 부모func1 { cout << "부모1" << endl; } }; class 부모2 { public: void 부모func2() { cout << "부모2" << endl; } };
class 자식 : public 부모1, public 부모2 { public: void func() { 부모func1(); 부모func2(); } };
int main() { 자식 child;
자식.func();
return 0;
} ```
c++무한대표현하기.무한값 표현하기 (0) | 2018.11.04 |
---|---|
템플릿 (0) | 2018.02.06 |
상속 (0) | 2018.02.06 |
동적배열과 이차원 동적배열 (0) | 2018.02.06 |
const (0) | 2018.02.06 |
사람이라는 객체와 학생,선생님,사부님이라는 객체가 있다.
학생, 선생님, 사부님은 모두 사람이라는 객체이며 동시에 각각의 특성을 지닌다.
즉 사람이라는 객체를 기반으로 각각의 또다른 특성이 있게된다.
이렇듯 클래스도 여러 객체가 반드시 한객체의 성질을 기반으로 만들어 졌을때 기반이 되는 클래스를 부모 클래스라 하며 이에대한 특성을 갖는 클래스를 자식클래스라 한다.
부모는 자식을 품지만 자식은 부모를 품지 못한다를 기억하자.(부모가 자식을 품을떄 부모에게 없는 변수나 함수는 slicing된다.ㄷ)
정의
class <클레스명> : <접근제한자> <상속받을 클레스명> {
자식클레스에서 추가로 설정해줄 맴버변수나 함수 만들기]
};
그렇다면 위에 <접근제한자> <상속받을 클레스명> 에서 접근제한자의 역할은 무엇일까??
private로 상속시 private보다 넓은 접근 범위(protect,public)의 맴버변수및 함수들을 private접근 제한자로 변환시킨다는 의미이다.
즉 부모클래스의 private는 private로 유지가 되고 나머지 변수및 함수 모두 private 처리되므로 자식클래스 및 외부클레스 에서는 접근이 불가능하다.
private는 그대로두고, protect보다 넓은 범위인 public을 protect로 변환한다.
protect의 상속은 조금 헷갈릴 수 있다.
protect로 상속하는 경우 부모클레스의 protect와 public 클레스 범위 의 함수나 변수를 사용 할 수 있다.(이때 public -> protect로 되겠지?)
하지만 protect는 외부 객체에서 참조가 불가능하다
예를들면
class 부모 {
protect:
function ~;
}
class 자식 :
protect : 부모
{
}
int main(){
자식.객체;
자식.function -->오류 발생!
}
템플릿 (0) | 2018.02.06 |
---|---|
오버라이딩 (0) | 2018.02.06 |
동적배열과 이차원 동적배열 (0) | 2018.02.06 |
const (0) | 2018.02.06 |
operator overloading(연산자 오버로딩) (0) | 2018.02.05 |
c언어에서의 변수로 공간을 할당하기 위한 '함수' malloc 과 free 를 대신하여 c++에서는 공간 할당하기 위한 '연산자' new와 공간해제를 위한 delete 가 사용된다.
정의-1 길이로 초기화
<자료형>* 변수명1;
변수명1= new int [원하는 길이의 변수명];-->길이가 원하는길이의 변수명만큼의 길이로 정해짐
정의-2 값으로 초기화
변수명1= new int (원하는 값의 변수명);-->값이 원하는 값으로 초기화가 됌
-->참고로 두개를 동시해 사용하는것은 불가능하다.
정의-3 변수를 넣지않고 초기화
변수명1= new int;-->변수타입 6개정도가 0으로 할당되어 초기화됌
정의
delete[] 변수명;
이차원 동적 배열
정의
1.가로포인터할당
이차원포인터 = new <데이터타입>*[가로길이];
-->직역하자면 가로길이만큼의 배열인데 이는 각각 데이터 타입의 포인터를 담겠다를 의미.
2.세로길이 할당
for(int i=0;i<가로길이;i++){
이차원포인터[i]=new int[세로길이];
}
-->각 가로의 포인터배열에 새로길이를 나타내는 포인터를 담아준다.
이차원 동적 배열 해제
정의
1.가로 해제
for(int i = 0 ; i<가로길이 ;i++){
delete[] 이차원포인터[i];-->가로에 할당된 배열을 해제시킨후
}
2.맨 앞부분 해제
delete[] 이차원포인터;
오버라이딩 (0) | 2018.02.06 |
---|---|
상속 (0) | 2018.02.06 |
const (0) | 2018.02.06 |
operator overloading(연산자 오버로딩) (0) | 2018.02.05 |
vector_static변수_static함수 (0) | 2018.02.05 |
const <리턴> 클래스명::함수명(매개변수){...}-->리턴값.즉 나의 맴버변수값을 보호!
<리턴> 클래스명 :: 함수명 (const 매개변수)-->매개변수를 보호!
상속 (0) | 2018.02.06 |
---|---|
동적배열과 이차원 동적배열 (0) | 2018.02.06 |
operator overloading(연산자 오버로딩) (0) | 2018.02.05 |
vector_static변수_static함수 (0) | 2018.02.05 |
클레스 (0) | 2018.02.05 |
기존에 우리가 사용하는 연산자를 추가한다.
예를들어 인스턴스 a와 b가 있다고 가정해보자.
무작정 a=b를 하면 오류가 발생한다.
그 이유는 "=" 이라는 대입연산자는 내가 정의한 클래스를 어떠한 방식으로 대입해주어아햐 할지 모르기 때문이다.
하지만 사용자는 멤버변수를 복사하고 싶을것이다.
이를 위하여 나온것이 연산자 오버로딩(operator overloading)이다.
정의
class 클래스명
~
const 클래스명 operator+(<데이터타입> 변수명) -->데이터타입과 변수명은 +연산시 우측값
{
return 클래스명(합친값)-->리턴으로 새로운생성자전달
}
};
-->이런식으로 한다면 <클래스명> 인스턴스1=인스턴스2+100;-->이런게 가능해진다.
인스턴스++ -> 이런식으로 했을때 모든 맴버변수가 1씩증가하면 좋겠다.
정의--이제 모두 int형 맴버변수와 매개변수를 받겠다고 가정하겠다.
<클래스명> operator++(int) -->애매하게 매개변수가 int가들어가면 후위,없으면 전위!
{
맴버변수+=1;
return *this; -->this는 인스턴스의 주소로 *는 값을 넘겨주겠다는 의미이다.
}
클래스명& operator = (student& RightValue){
<기존에 있던값듨 삭제--동적배열 delete>
<맴버변수 deep copy>
return *this;
}
정의
ostream& operator<<(ostream &output, const CMoney &r1)
{
cout << r1.m_nDollar << r1.m_nCent;
return output;
}
-->cout의 주소 포트가 output이다. 출력후 리턴해주는 방식이다.
연산자 오버로딩은 /= %= <<= += -= *= >>= &= |= ^= 이렇게 종류가 매우 다양하다.
전역함수가 맴버변수에 접근할때 사용된다.
정의 - 클래스의 헤더파일부분
class 클래스명{
pulblic:
friend 전역함수;
};
위에서 + 연산자를 보면 class+정수 만된다.
하지만 정수 + class 가 나오는경우도 있다.
이런경우 value를 좌우측에서 동시에 받아야 하므로 이때 friend함수를 이용한다.
using namespace std;
class <클래스명>
{
public:
friend <클래스명> operator+(int <좌측변수>, <클래스명> <우측변수>);
};
<클래스명> operator+(int <좌측변수>,<클래스명> <우측변수>);
{
<우측변수>.num1 += <좌측변수>;
<우측변수>.num2 += <좌측변수>;
return 우측변수;
}
int main()
{
<클래스명> 변수명 = 10 + 다른클래스변수명 ;
}
동적배열과 이차원 동적배열 (0) | 2018.02.06 |
---|---|
const (0) | 2018.02.06 |
vector_static변수_static함수 (0) | 2018.02.05 |
클레스 (0) | 2018.02.05 |
함수 default (0) | 2018.02.05 |
array와 달리 한번정한 크기를 바꿀 수 없다.
그러나 vector는 크기를 가변적으로 바꿀 수 있다.
정의는
vector<type> 변수명;
예제
이밖에 여러 맴버 함수가 존재한다.
static 변수는 class 내에서도 맴버변수로 사용 될 수 있다.
그냥 맴버변수는 인스턴스가 생성될때마다 새로 공간이 할당되어지지만, static 맴버변수는 모든 인스턴스에서 동일하다. 또한 공단도 새로 할당되어지지 않는다.
접근지정자 역시 사용가능하며 맴버변수를 선언할때 앞에 static을 붙여주면 된다.
헤더파일에서의 정의
class <클래스명> {
...
<접근 제한자>:
static <데이터타입> <데이터명>; --->선언은 하되 초기화는 해주지 않는다.!
--->클래스내에서 하면 에러가 발생한다.
--->클래스 외부에서 전역변수처럼 초기화!
...
}
main이 들어있는 cpp
#include <iostream>
using namespace std;
<데이터 타입> <클래스명>::<static 변수명> = <초기화값>;
int main(){
}
static 에 접근하는 방법
int main(){
<클레스명>::<static변수명>-->클래스의 함수 쓰듯이 사용한다.
}
static 함수 내에서는 static 변수만 사용이 가능하다.
static 함수에서 맴버변수는 사용이 불가능하다.
이는 다른 구간의 지역변수를 사용하는것과 동일한 이치이다.
헤더파일에서 선언
static <return type> 함수명 ();
cpp파일에서의 선언
<return type> <class 명>::<함수명>(){
}
--->cpp파일에서는 일반 함수 선언과 동일하며 앞에 static은 붙지 않는다
--->body에 변수는 static변수만 이용가능하며 맴버변수는 불가능하다.
main에서의 사용
int main(){
클래스명::함수명();-->객체를 생성하여 사용하지 않고 클래스에서 불러와 사용.
}
const (0) | 2018.02.06 |
---|---|
operator overloading(연산자 오버로딩) (0) | 2018.02.05 |
클레스 (0) | 2018.02.05 |
함수 default (0) | 2018.02.05 |
overloading (0) | 2018.02.05 |