템플릿(template)

- 다양한 타입에 대해 같은 일을 하는 기능

 

함수 템플릿

template<typename T>
T get_max(T a, T b){
	return a > b ? a : b;
}

데이터 타입을 변수처럼 표시해서 다양한 데이터 타입에서 사용가능하게 함.

 

 

 

함수 템플릿의 특수화

만약 char인 경우만 다르게 표현하고 싶다면!

template<>
char get_max(char a, char b){
	return a;
}

 

 

 

여러 개의 타입 매개 변수를 가지는 함수 템플릿

template<typename T1, typename T2>
T1 printsum(T1 a, T2 b){
	return a + b;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

클래스 템플릿

template<typename 타입이름> 
class classname
{
	...
}
템플릿 클래스 구현

template<typename T>
class Box{
	...
};


int main(){

	Box<int> a;
    Box<float> b;
    Box<string> c;
}

 

 

 

 

 

 

 

 

 

 

 

 

클래스 외부에 멤버 함수를 정의하는 경우

- 함수 템플릿처럼 함수 정의 앞에 template<typename ..>를 써야한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

클래스 템플릿의 매개 변수에도 디폴트 값을 부여할 수 있다.

template<typename T = int>
~~~~

ex) Box<> box;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

템플릿 사용의 장점

-클래스를 생성하기 전까지 코드가 생성되지 않는다.(코드의 크기를 증가시키지 않는다)

 

 

 

 

 

 

 

 

 

 

 

 

 

정적 멤버는 클래스 템플릿으로 생성된 모든 클래스에 대하여 각각 하나씩 생성된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

스택(stack)

후입 선출(LIFO: Last in First out) - 마지막에 드간놈이 젤 먼저 티나온다.

 

스택이 가지는 연산

is_empty

is_full

push

pop

 

 

'Power C++' 카테고리의 다른 글

ch-13, 14 상속, 다형성  (0) 2022.01.08
ch12 프렌드와 연산자 중복  (0) 2022.01.07
ch11 클래스의 활용  (0) 2022.01.06
ch09,10 클래스의 기초, 생성자와 소멸자  (0) 2022.01.03
ch07 향상된 C언어  (0) 2022.01.01

상속은 is-a관계

ex) 자동차는 탈것이다.(Car is a Vehicle).

 

has-a관계는  상속으로 모델링하면 안된댜~

ex) 도서관은 책을 가지고 있다.

has-a관계는 하나의 클래스 안에 다른 클래스의 객체를 포함시키면 된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

상속의 생성자/소멸자

 

자식 클래스의 객체가 생성될 때 자식 클래스의 생성자에서는 부모 클래스의 생성자를 호출하다.

생성자 : 부모 -> 자식

소멸자 : 자식 -> 부모

 

특별히 생성자를 지정하는 법

자식클래스의 생성자(): 부모클래스의생성자()
{
	...
}

재정의의 조건 - 멤버 함수의 헤더는 그대로 두고 몸체만 교체. 헤더 부분은 부모 클래스의 헤더와 동일하여야 한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

멤버의 재정의(overridiing)

 

childclass obj;

obj.parentclass::method() ;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

다형성(polymorphism)

객체들의 타입이 다르면 똑같은 메시지가 전달되더라도 서로 다른 동작을 하는 것을 말한다.

 

 

 

 

상향 형변환

class Animal

class Dog : public animal

class Cat : public animal

인 상황에서

Dog dog;
Animal* pa;
pa = &dog;

이게 될까?

 

- 된다. 자식 클래스 객체는 부모 클래스 객체를 포함하고 있기 때문에 자식 클래스 객체는 부모 클래스 객체이기도 하다.

-상향 형변환(up-casting)을 하면 부모 클래스로부터 상속받은 부분만 포인터를 통해 사용할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

하향 형변환

Animal* pa = new Dog();

Dog* pd = (Dog*)pa;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

부모 클래스 포인터 변수는 자식 클래스 객체를 참조할 수 있다. 역은 성립하지 않는다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

함수의 매개 변수는 자식 클래스보다는 부모 클래스 타입으로 선언하는 것이 좋다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

가상함수(virtual function)

부모클래스의 포인터로 호출하더라도 부모 클래스의 함수가 가상 함수로 정의되어 있으면 자식 클래스의 재정의된 함수가 호출된다.

 

class shape{
    public:
    int b;
    virtual void repr(){
        cout << "hello" << endl;
    }

};

class circle : public shape{
    public:
    int a;
    void repr(){
        cout << "1231231" << endl;
    }
};


================================
    shape* ptr = new circle();
    ptr->repr() ;            -> circle의 함수가 실행된다.

virtual 키워드는 멤버 함수에만 사용할 수 있다.(멤버 변수에 사용 X)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

동적 바인딩

- 함수 호출을 실제 함수의 몸체와 연결하는 것을 바인딩이라고 한다.

정적 바인딩 - 컴파일 단계에서 모든 바인딩이 완료되는 것. 속도가 빠름

동적 바인딩 - 바인딩이 실행 시까지 연기되고 실행 시간에 실제 호출되는 함수를 결정하는 것. 속도가 느림

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

가상함수의 구현 

- 가상함수는 v-table이라고 불리는 테이블에 의하여 구현 

- circle 객체는 내부에 shape에 해당되는 부분과 circle에 해당되는 부분을 가지게 된다.

- 객체 안에서 가상 함수가 정의되면 각각의 객체는 이들 가상 함수를 관리하는 테이블을 만들게 된다. 객체가 생성되어서 shape부분이 생성되면 가상 함수 테이블은 shape안의 멤버들의 주소를 가지게 된다. 이어 circle부분이 추가로 생성되어 가상 함수가 재정의 되면 circle안의 멤버 함수 주로소 테이블의 내용이 변경된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

다형성을 사용하는 과정에서 소멸자를 virtual로 해주지 않으면 문제가 발생한다.

소멸자를 virtual로 해주지 않으면 부모 클래스 포인터가 소멸할 때 부모 클래스의 소멸자만 생성이 된다.

-> 부모 클래스의 소멸자를 virtual로 한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

순수 가상함수

- 함수 헤더만 존재하고 몸체는 없는 함수.

 

virtual 반환형 함수이름(매개변수) = 0;
virtual 반환형 함수이름(매개변수){
	...
}

가상함수와는 다르다.

 

순수 가상 함수를 하나라도 가지고 있는 클래스를 추상 클래스(abstract class)라고 한다.

 

주의할 점. 

-> 부모 클래스가 추상 클래스이기 때문에 부모 클래스로는 객체를 생성할 수 없다.

다만 포인터 변수는 생성할 수 있고 이 포인터 변수를 통해 자식 클래스의 객체를 가리킬 수 있다.

 

 

 

 

 

 

 

 

 

 

추상 클래스를 상속받으면 추상 클래스에 포함된 모든 가상 함수를 구현하여야한다.

클래스가 추상 클래스에 있는 하나의 가상 함수라도 빠뜨린다면 컴파일러는 해당 클래스도 추상 클래스로 정의되어야한다고 알린다.

 

 

 

'Power C++' 카테고리의 다른 글

ch-17 템플릿  (0) 2022.01.09
ch12 프렌드와 연산자 중복  (0) 2022.01.07
ch11 클래스의 활용  (0) 2022.01.06
ch09,10 클래스의 기초, 생성자와 소멸자  (0) 2022.01.03
ch07 향상된 C언어  (0) 2022.01.01

프렌드 함수

멤버 함수가 아니지만 클래스의 내부 데이터에 접근할 수 있음.

 

class myClass{
	friend void sub();  // 요게 friend
};

void sub(){}

원형은 내부에 정의되지만 본체는 외부에서 따로 정의된다

 

 

 

 

 

 

 

 

 

프렌드 클래스

- 마찬가지로 클래스 내부 데이터 접근 가능

class Employee{
	friend class Manager;
};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

연산자 중복

 

-연산자 중복의 형식

반환형 operator연산자(매개변수 목록)
{
   ...
 }

 

 

 

 

연산자 중복은 두 가지 방법으로 구현

1. 멤버 함수

2. 비멤버 함수(friend)

 

 

 

 

 

 

 

+ 연산자를 멤버, 비멤버 함수로 정의 해보자.

 

1. 산술연산

 

일반적으로 비멤버함수로 정의

###산술연산

### 멤버 함수

class myClass{
	publid:
    int a;
    myClass(int num): a(num){};
	myClass operator+(const myClass& cls);
}

myClass operator+(const myClass& cls){
	myClass obj(a + cls.a);
    return obj;
}



###비멤버함수

class myClass{
	publid:
    int a;
    myClass(int num): a(num){};
	friend myClass operator+(const myClass& cls1, const myClass& cls2);
}

myClass operator+(const myClass& cls1, const myClass& cls1){
	myClass obj(cls1.a + cls2.a);
    return obj;
}

 

 

 

 

2. 할당연산(=)

멤버 함수로 정의

할당연산자의 매개변수가 일반적으론 객체에 대한 레퍼런스 상수 이지만,

코드에 따라서 그냥 객체이거나, 상수가 아닌 레퍼런스일 수 있기때문.

 

###할당연산

### 멤버 함수

class myClass{
	publid:
    int a;
    myClass(int num): a(num){};
    myClass operator=(const myClass& cls);
}

myClass& operator=(const myClass& cls){
	this->a = cls.a;
    return *this;
}

### 컴파일러가 매개 변수를 변환할 수 있으려면 할당 연산자는 멤버 함수이어야한다.
### 할당 연산자는 레퍼런스를 반환한다. 할당 연산자는 연속하여 적용될 수 있기 때문이다.

ex)
a1 = a2 = a3;

 

 

 

 

 

 

 

 

3. 관계연산(==, !=)

비멤버함수로 정의

###비교연산

###비멤버함수

class myClass{
	publid:
    int a;
    myClass(int num): a(num){};
	friend bool operator==(const myClass& cls1, const myClass& cls2);
}

bool operator==(const myClass& cls1, const myClass& cls1){
	return cls1.x == cls2.x
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4. <<, >> 연산

- 다시 스트림 객체를 반환하여야한다.

- 현재 객체의 const 객체를 받아야한다.

###<< , >> 

### 반드시 비멤버 함수로 작성
### 멤버함수로 정의하면 << 왼쪽에 객체가 와야하는데 그럼 틀림.

class myClass{
	publid:
    int a;
    myClass(int num): a(num){};
	friend ostream& operator<<(ostream os,  const myClass& cls);
    friend istream& operator<<(istream is,  const myClass& cls);
}

ostream& operator<<(ostream os,  const myClass& cls){
	os << cls.x << endl;
    return os;
}

istream& operator<<(istream is,  const myClass& cls){
	is >> cls.x;
    return is;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

타입 변환

 

1. 변환 생성자 - 매개변수가 하나인 생성자를 사용해서 다른 타입을 우리의 클래스 타입으로 변경

2. 변환 연산자 - 클래스 타입을 다른 타입으로 자동 변환

 

 

 

 

변환 생성자

class book{
	public:
    int isbn;
    string title;

	book(){
    	isbn = 0;
        string = "unknown";
    }
    
    book(int isbn){
        this->isbn = isbn;
        this->title  = "unknown";
}


int main(
	book b1 = 9123232;
   }

 

 

 

 

 

 

 

 

 

 

변환 연산자

 

class book{
	public:
    int isbn;
    string title;

	book(){
    	isbn = 0;
        string = "unknown";
    }
    book(int isbn){              ## 변환 생성자
    	this->isbn = isbn;
    	this->title  = "unknown";
    }
    operator int() const{        ## 변환 연산자
    	return isbn;
     }
}


int main(
	book b1 = 91823213;
    int isbn = b1;
   }

'Power C++' 카테고리의 다른 글

ch-17 템플릿  (0) 2022.01.09
ch-13, 14 상속, 다형성  (0) 2022.01.08
ch11 클래스의 활용  (0) 2022.01.06
ch09,10 클래스의 기초, 생성자와 소멸자  (0) 2022.01.03
ch07 향상된 C언어  (0) 2022.01.01

객체 포인터를 사용해서 객체의 멤버들을 접근하고싶다

Car* pcar = new Car();

pcar->num;
pcar->setNum;

화살표 사용

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

this포인터

객체 자기 자신을 가리키는 포인터.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Const 수식자

1. 멤버 변수에 붙이는 경우

- 상수가 된다. 

 

2. 멤버 함수에 붙이는 경우

- 이 함수를 통해서 멤버 변수를 변경할 수 없다는 뜻

void getNum() const{
	cout << this->num;
}

 

 

3. 객체에 const를 붙이는 경우

- 해당 객체의 멤버 변수의 값을 변경할 수 없다.

- const가 붙은 상수 함수외의 함수도 호출할 수 없다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

객체와 함수의 관계

1. 객체가 함수의 매개 변수로 전달되는 경우

2. 함수가 객체를 반환하는 경우

3. 객체의 포인터가 함수로 전달되는 경우

4. 객체의 레퍼런스가 함수로 전달되는 경우

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

정적 멤버

 

- 정적 멤버 변수

  모든 객체에 공통인 변수

  정의는 반드시 클래스 외부에서 초기화하여야한다.

  객체를 통해서도 접근할 수 있다.

 

Car::numberOfCars = 100;
c1.numberOfCars = 50;

 

- 정적 멤버 함수

  객체 안에서만 존재하는 인스턴스 변수들은 사용할 수 없고 정적 변수, 지역 변수만 사용 가능

'Power C++' 카테고리의 다른 글

ch-13, 14 상속, 다형성  (0) 2022.01.08
ch12 프렌드와 연산자 중복  (0) 2022.01.07
ch09,10 클래스의 기초, 생성자와 소멸자  (0) 2022.01.03
ch07 향상된 C언어  (0) 2022.01.01
ch06 포인터와 문자열  (0) 2021.12.31

멤버 함수의 외부 정의

class A{
	public:
    int var;
	void getVar();
}

void A::getVar(){
	cout << var << endl;
}

멤버 함수가 클래스 내부에 정의되면 인라인 함수가 된다.

멤버 함수가 클래스 외부에 정의되면 일반적인 함수와 동일하게 호출된다. 스택에 인자들을 저장하고 복귀 주소를 저장한 후에 멤버 함수로 제어가 이동된다

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

UML에서 멤버 변수나 함수 옆에 가시성 표시자로 +는 public, -는 private를 의미한다.

 

실선에 속이 빈 삼각형 화살표는 상속을 나타낸다. 방향표 쪽에 있는 클래스가 부모 클래스.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

생성자에서 다른 생성자 호출하기.

생성자들은 보통 비슷한 초기화 작업을 수행하기 때문에 하나의 생성자에서 다른 생성자를 호출하는 경우도 많다.

class Car{
	int speed;
    int gear;
public:
	Car(int a, int b){
    	speed = a;
        gear = b;
    }
    
    Car(int a){
    	Car(a,0); //요런식으루
    
    }

 

 

 

 

 

 

 

 

 

 

 

 

생성자에서 동적 메모리 할당을 하는 경우면 눈치껏 소멸자만들어서 메모리 반납하자.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

초기화리스트

class Car{
	int speed;
    int gear;
    const int MAX_SPEED;
    String& name;
public:
	Car(int a, int b, string c): speed(a), gear(b), MAX_SPEED(300), name(c){ //요런식으루
    	speed = a;
        gear = b;
    }
    
    Car(int a){
    	Car(a,0); 
    
    }

초기화리스트를 사용해야만 하는 경우!!!

1. 멤버가 상수인 경우

 

ex) Const int MAX_SPEED; 가 선언되어 있는 경우

 여기에 값을 주면 컴파일 오류가 발생 -> 객체가 생성되지 않았기 때문에

 

2. 멤버가 레퍼런스인 경우

 

- 레퍼런스는 선언 시에 참조하는 변수가 결정되어야하기 때문

 

 

3, 멤버가 객체인 경우

 

A클래스에 B클래스의 객체가 멤버 변수로 들어가 있을 경우,

A클래스에서 B클래스의 생성자를 호출할 수 없다(생성자는 객체가 생성될 때 호출되기 때문에)

디폴트 생성자를 호출하는 경우가 아니라면, 초기화리스트를 사용해야한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Power C++' 카테고리의 다른 글

ch12 프렌드와 연산자 중복  (0) 2022.01.07
ch11 클래스의 활용  (0) 2022.01.06
ch07 향상된 C언어  (0) 2022.01.01
ch06 포인터와 문자열  (0) 2021.12.31
ch05 배열과 구조체  (0) 2021.12.31

레퍼런스(reference) : 변수의 별명.

#레퍼런스 선언 및 초기화
int& ref = var;

 

- 레퍼런스는 메모리 공간에 할당되지 않는다.(가리키는 대상이 변경될 수 없다.)

- 레퍼런스는 반드시 선언과 동시에 초기화되어야한다.(NULL이 될 수 없다)

- 레퍼런스를 상수로 초기화하면 컴파일 에러

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

포인터 vs 레퍼런스

- 참조하는 대상이 수시로 바뀌는 경우 -> 포인터 (레퍼런스는 변경 불가)

- NULL이 될 가능성이 있는 경우 -> 포인터 (레퍼런스는 NULL값 가질 수 없음)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

디폴트 매개변수를 선언 시 뒤에서부터 앞쪽으로만 정의 가능

 

 

 

 

 

 

 

 

 

 

 

중복 함수(overloading)의 구분은 매개 변수의 개수와 타입으로 구분.

 

 

 

 

 

 

 

 

 

 

 

 

 

인라인 함수 

일반적인 함수 호출 시 -> 함수가 정의된 곳으로 점프하여 함수 안의 문장들을 차례로 실행하고 다시 호출한 곳으로 되돌아온다. 함수를 호출할 때는 돌아올 곳의 주소를 스택에 저장하고, 전달되는 값들을 스택에 저장하여야한다.

크기가 작은 함수의 경우, 함수 호출을 하지 않고 코드를 복붙해서 넣어주는 편이 효율적이다 -> 인라인 함수 사용

그냥 함수 앞에 inline키워드 사용

 

 

 

 

 

 

 

 

 

 

 

 

 

 

malloc, free vs new, delete

- malloc와 free는 헤더파일 필요, new, delete는 언어에서 제공하는 기본 키워드 (malloc은 함수, new는 연산자)

- malloc은 해당 포인터의 자료형을 모르기 때문에 void* 로 리턴한다. 때문에 malloc 사용시 type casting을 해주어야 한다.
- 하지만 new의 경우 해당 객체에 맞는 포인터를 반환한다. 따라서 자료형을 따로 적어주지 않아도 된다.new를 이용해 객체를 생성하면 생성자를 자동으로 호출하여 초기 값을 줄 수 있다. 하지만 malloc의 경우 생성자 호출 기능이 없어 초기값을 줄 수 없다.

- free와 delete는 메모리를 해제하는 것은 동일하지만 delete는 소멸자를 호출한다.malloc의 경우 realloc을 이용해 메모리 크기를 조정할 수 있다. 하지만 new는 할당된 크기에 대한 메모리 재조정이 불가능하다. 재조정하기 위해서는 새로 할당, 복사, 해제 하는 과정을 통해야 한다. 따라서 객체가 아니고, 재할당이 빈번하게 일어나야 한다면 malloc이 좋은 선택이 될 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

namespace와 전역변수의 이름이 같을 경우의 접근

전역변수 -> ::var 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Power C++' 카테고리의 다른 글

ch11 클래스의 활용  (0) 2022.01.06
ch09,10 클래스의 기초, 생성자와 소멸자  (0) 2022.01.03
ch06 포인터와 문자열  (0) 2021.12.31
ch05 배열과 구조체  (0) 2021.12.31
ch04 함수(2)  (0) 2021.11.11

포인터(pointer) = 메모리의 주소를 가지고 있는 변수

 

 

변수의 주소를 알고싶다? => & 사용

 

int i = 10;
char c = 69;
cout << &i;     // 변수 i가 저장된 메모리의 주소가 출력
cout << (void*)&c;  //


##포인터 선언 및 초기화 방법
#1
int* ptr;
ptr = &i;
#2 
int* ptr = &i;

 

 

 

 

 

 

 

void 포인터

- void 포인터는 자료형이 정해지지 않은 특성 때문에 어떤 자료형으로 된 포인터든 모두 저장할 수 있다. 반대로 다양한 자료형으로 된 포인터에도 void 포인터를 저장할 수도 있다. 이런 특성 때문에 void 포인터는 범용 포인터라고 불린다.

 

단, void 포인터는 자료형이 정해지지 않았으므로 값을 가져오거나 저장할 크기도 정해지지 않았기 때문에 void 포인터는 역참조를 할 수 없다.

 

ptr = numPtr1;        // void 포인터에 int 포인터 저장
printf("%d", *ptr);   // void 포인터는 역참조할 수 없음. 컴파일 에러

 

 

 

 

 

 

 

 

주소는 한 가지 형식인데 포인터에 다양한 타입이 존재하는 이유

-> 메모리상에서 주소는 동일한 크기이기 때문에 어떤 형태이든 주소의 형식은 차이가 없지만, 포인터가 가리키는 타입을 확실하게 함으로써 프로그래밍 실수를 예방하기 위해서

 

 

 

 

 

 

 

 

 

 

 

 

 

역참조시 괄호를 사용해서 연산자의 우선순위로 인해 계산이 꼬이는 상황 방지

ex) (*ptr)++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

포인터가 선언만 되고 초기화되지 않았다면 포인터는 임의의 주소를 가르키게 됨.

->NULL로 초기화화는 편이 좋다.!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

배열의 이름은 포인터이다 -> 배열의 이름에다 다른 변수의 주소를 대입할 수 있을까?

 

-> no , 배열의 이름은 포인터 상수이다. 값 변경 불가

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

포인터가 실제로 사용되는 경우

-> 동적으로 할당된 메모리 사용

-> 함수의 매개 변수로 변수의 주소를 전달

-> 클래스의 멤버 변수나 멤버 함수 호출

 

 

1, 동적으로 할당된 메모리 사용

new, delete 사용

동적 메모리의 위치 = 힙

힙에서 할당받으면 함수가 종료되더라도 메모리 공간에서 없어지지 않기 때문에 반드시 반납해야함.

 

 

메모리의 공간

1, 코드 : 프로그램 코드 저장

2, 전역 : 전역변수 global, 정적변수 static, 배열 array, 구조체 structure 등이 저장

3, 스택 : 함수 호출 시 함수의 매개 변수와 지역 변수 생성. 함수 호출이 끝나면 자동으로 소멸

4, 힙 : 동적 할당으로 사용 가능

 

new 키워드가 반환하는 것은 할당된 메모리의 주소

만약 delete 키워드를 사용하여 반납하지 않을 시, 메모리 누수(memory leak)발생.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

const int* p1 vs int* const p1

 

const int* p1

-> p1이 담고자하는 주소에는 const int가 저장되어 있다.

 

int* const p1

-> p1이 담고자하는 주소에는 int가 저장되어 있고, 이 값(주소)는 변경할 수 없다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2, 함수의 매개 변수로 변수의 주소를 전달

 

참조에 의한 호출(call by reference)

 

1, 포인터 이용

 

void func(int* a, int* b){}

int main(){
int A = 10;
int B = 20;

func(&A, &B);
}

 

2, 레퍼런스 이용

 

void func(int& a, int& b){}

int main(){
int A = 10;
int B = 20;

func(A, B);
}

2가 더 깔끔하다.함수의 매개 변수로 변수의 주소를 전달함수의 매개 변수로 변수의 주소를 전달

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C-문자열

c++에서는 문자열의 끝이 반드시 NULL로 끝나야 한다.

 

문자열을 나타내는 두 가지 방법.

1. 문자 배열을 생성하고 맨 끝에 NULL문자를 추가 (NULL문자는 ASCII코드값이 0)

2. 클래스 String 사용

 

char str[] = "hello";

 

 

 

대문자는 소문자보다 아스키 코드값이 작다.

char s1[3] = "cat";
char s2[6] = "catdog";

strcmp(s1, s2)    // strcmp에서는 사전 기준으로 s1이 낮으면 음수, 같으면 0,높으면 양수를 반환한다
                  // s1의 t이후 값이 0(NULL)이기때문에 음수가 반환된다.

 

'Power C++' 카테고리의 다른 글

ch09,10 클래스의 기초, 생성자와 소멸자  (0) 2022.01.03
ch07 향상된 C언어  (0) 2022.01.01
ch05 배열과 구조체  (0) 2021.12.31
ch04 함수(2)  (0) 2021.11.11
ch04 함수(1)  (0) 2021.11.03

배열(array) : 동일한 타입의 데이터각 여러 개 저장되어 있는 데이터 저장 장소

 

배열도 변수와 마찬가지로 지역?에서 선언되면 초기화되지 않으면 쓰레기값이 들어감.

 

배열 대입 연산 

int arr[10];

arr1 = arr2 // 컴파일 오류

 

배열의 이름은 배열이 저장된 메모리의 시작 주소와 같다

 

 

배열이 함수의 인자로 사용되는 경우 배열의 원본이 사용된다(call by reference)

참조만 할 수도 있긴하다( int& arr[])

 

 

함수 호출 시 변수와 달리 원본이 공유되는 이유?

-> 배열의 크기를 예측할 수 없다. 배열의 크기가 크다면 인자에서 매개변수로 복사하는 데 많은 시간이 소모됨.

-> 호출된 함수들의 대부분이 배열을 조작.

 

함수에서 배열을 읽기 전용으로 사용하고 싶다면

-> int func(const int arr[])

 

함수에서 다차원 배열을 인자로 보내고 싶다면

-> 함수 정의 시 첫 번째 인덱스의 크기를 제외한 나머지 인덱스의 크기는 적어야 함

ex) int sum(int grade[][num]);

 

'Power C++' 카테고리의 다른 글

ch07 향상된 C언어  (0) 2022.01.01
ch06 포인터와 문자열  (0) 2021.12.31
ch04 함수(2)  (0) 2021.11.11
ch04 함수(1)  (0) 2021.11.03
ch02 자료형과 연산  (0) 2021.10.20

변수의 범위(scope)

 

지역변수(local variable)

- 변수가 선언된 블록이 시작할 때 스택에 만들어지며 동시에 초기화

함수의 매개변수 또한 일종의 지역 변수이다.

 

 

전역변수

- 소스 파일 전체에서 접근이 가능하고 사용이 가능

전역변수의 초기값과 생존 기간

- 초기화 하지 않으면 0으로 초기화된다.

- 생존기간은 프로그램이 시작부터 종료까지

- 정적 할당 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

저장 유형 지정자(storage class specifier)

- 변수를 선언할 때 앞에 저장 유형을 지정

auto it ## 변수를 선언한 위치에서 자동으로 만들어지고 블록을 벗어나면 자동으로 소멸 
        ## default값이 auto
register it ## 메모리에 저장이 아닌 레지스터에 저장.
static it  ## 지역 변수에 사용 시 전역 변수와 같이 프로그램이 시작 시 생성되고 종료 시 제거된다.
extern it ## 변수가 현재 범위가 아닌 다른 곳에서 선언되었다는 것을 알리는 역할. 
          ## 반드시 다른 소스 파일에서 정의되거나 같은 파일의 다른 부분에서 정의되어야 한다.
          ## 정적할당으로 간주

 

 

static을 지역 변수에 사용 시 전역 변수와 같이 프로그램이 시작 시 생성되고 종료 시 제거된다.

전역 변수에 사용하면 내부 연결, 즉 현재 소스 파일에서만 사용이 가능하고 다른 소스 파일에서는 해당 변수를 사용할 수 없다.

 

함수 이름 앞에 사용하는 경우 해당 함수는 현재 소스 파일에서만 사용이 가능하다.(정적 함수)

함수앞에 static이 없다면 외부 소스 파일에서 extern을 선언하여 사용할 수 있다.

 

 

 

 

 

'Power C++' 카테고리의 다른 글

ch06 포인터와 문자열  (0) 2021.12.31
ch05 배열과 구조체  (0) 2021.12.31
ch04 함수(1)  (0) 2021.11.03
ch02 자료형과 연산  (0) 2021.10.20
ch01 C++ 소개  (0) 2021.10.19

함수(function) - 특정 작업을 수행하여 그 결과를 반환하는 문장들의 집합.

 

 

함수가 프로그래머가 직접만든 함수라면 -사용자 정의 함수(user-defined function)

컴파일러 차원에서 지원되는, 미리 만들어진 함수라면 - 라이브러리 함수(library function)

 

 

 

 

 

C++에서 함수 정의 형식

ex)

int add(int x, int y)
{
    int result;
    result = x + y;
    return result;
}

int -> 반환형 (함수가 return하는 데이터의 유형, result는 int타입이다)

add -> 함수 이름

int x -> 매개변수 1(외부에서 함수 호출시 함수 작업에 필요한 데이터)

int y -> 매개변수 2

{ } -> 함수 몸체(body)

 

함수의 특징)

- 매개변수는 여러 개일 수 있지만, return값은 반드시 한 개이다(void의 경우 0개) (여러개를 사용하고 싶으면 포인터, 레퍼런스 사용)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

함수 원형(function prototype)

- 함수를 사용할 때는 미리 컴파일러에게 함수에 대한 정보를 알려야 한다

int sqrt(int , int);

int main(){
    a = sqrt(2,4);
}

int sqrt(int a, int b){}

위와 같이, 함수의 이름, 매개 변수 타입, 반환형만 우선적으로 작성하고 ;를 붙인다.

 

쓰는 이유 -> 컴파일러에게 미리 함수에 대한 정보를 주어 함수의 매개 변수, 반환형 검사 등을 하게 하기 위함.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

디폴트 매개변수

-함수 원형 정의 시에 디폴트 매개 변수를 넣어서 인자를 외부에서 전달하지 않아도 디폴트값을 대신 전달해줄 수 있다.

 

int sqrt(int , int);

int main(){
    m = sqrt(2,4);
    n = sqrt();  //n은 a = 1, b = 2의 값을 가진다.
}

int sqrt(int a = 1, int b = 2){}

# 디폴트 매개변수는 뒤에서부터 앞쪽으로만 정의할수 있다.

int sqrt(int a, int b = 2){}

가능

int sqrt(int a = 1, int b){}

불가능

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

중복 함수(oveloading function)

- 같은 이름의 함수가 여러 개 존재할 수 있다.

- 다른 종류의 데이터에 같은 처리를 수행하는 경우에 사용

int multiplication(int m, int n){return m*n;}
double multiplication(double m, double n){return m*n;}

하지만, 반환형을 사용해서 구별하지는 않는다. 즉,

int multiplication(int m, int n){return m*n;}
double multiplication(int m, int n){return m*n;}

이건 안된다는 소리

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

인라인 함수

일반적으로 함수를 호출하면 컴퓨터 시스템은 함수가 정의된 곳으로 점프하여 함수 안의 문장들을 차례대로 실행하고 다시 호출한 곳으로 되돌아오게 된다. 즉, 함수를 호출할 때는 돌아올 곳의 주소를 스택에 저장하고 전달되는 인자들을 스택에 저장해야한다. 함수 구성이 간단하다면 인라인 함수를 사용하는 것이 효과적이다.

- 함수 호출을 하지 않고 코드를 복사하여 넣어 준다.

- 함수 호출 오버헤드가 사라져 프로그램이 더 빠르게 실행될 수 있다.

int main(){
	int result = multiply(10,5);
    return 0;
}

inline int multiply(int a, int b){
	return a*b;
}

함수 헤드부분에 inline을 적어주기만 하면 끝

 

다만, 함수 호출이 여러 번 이루어지면 코드가 반복 복사되어 전체코드의 크기가 늘어나게된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Power C++' 카테고리의 다른 글

ch06 포인터와 문자열  (0) 2021.12.31
ch05 배열과 구조체  (0) 2021.12.31
ch04 함수(2)  (0) 2021.11.11
ch02 자료형과 연산  (0) 2021.10.20
ch01 C++ 소개  (0) 2021.10.19

+ Recent posts