반응형
생성자(Constructor)

생성자는 객체 생성시 딱 한번 호출되는 함수로, 객체의 초기화를 담당한다.

생성자는 클래스나 구조체의 이름과 동일해야 하고, 반환 타입을 가지지 않는다.

생성자를 선언할 때

class MyClass {
public:
    MyClass() {
        // 기본 생성자 : 클래스와 이름이 같고 반환형이 없다
        // 초기화 작업 수행
    }

    MyClass(int value) {
        // 매개변수를 받는 생성자
        // 초기화 작업 수행
    }
};

 

 

생성자 특징

1. 객체가 생성될 때 자동으로 호출.

2. 클래스 내부에 여러 개의 생성자를 오버로딩할 수 있다.

3. 생성자를 정의하지 않을때 컴파일러가 기본 생성자(디폴트 생성자)를 자동으로 생성해준다.

4. 디폴트 값 설정이 가능하다. 기본 생성자와 디폴트 값이 설정되어 있어서

인자를 넘기지 않는 생성자는 다르다

5. 매개변수를 받아 멤버변수의 초기화 작업을 수행할 수 있다.

 

 

 

멤버 이니셜 라이저(Member Initializer)

C++의 멤버 이니셜라이저(Member Initializer)는 생성자에서 멤버 변수를

초기화하는 특별한 문법이다. 이니셜라이저는 생성자의 함수 몸체 이전에 사용되며,

멤버 변수의 초기값을 지정하는 역할을 해준다. 파일 분할을 할 시에는 일반적으로

선언부가 아닌, 정의부에 명시하며, 배열은 멤버 이니셜라이저를 사용할 수 없다.

#include <iostream>
class MyClass 
{
private:
    int value1;
    int value2;
public:
    // 멤버 이니셜라이저를 사용한 생성자
    MyClass(int num1, int num2) : value1(num1), value2(num2) 
    {
        // 추가적인 초기화 작업
        std::cout << "Constructor called. Value1: " << value1 << ", Value2: " << value2 << std::endl;
    }
};
int main() 
{
    MyClass obj(10, 20);
    return 0;
}

 

 

멤버 이니셜라이저 특징

1. 효율성 : 이니셜라이저를 사용하면 객체 생성 시 멤버 변수의 초기화를 생성자 함수 몸체 안에서

생성하는 것보다 더 효율적으로 생성할 수 있습니다. 생성자 함수 몸체에서 초기화시, 멤버 변수는

기본값으로 초기화되고, 그 다음 생성자의 함수 몸체 안에서 초기화 작업이 실행됩니다.

이니셜라이저를 사용하면, 멤버변수의 초기값을 직접 지정하여 중복된 초기화 작업을 피할 수 있습니다.

 

2. const 멤버 초기화 : const 멤버 변수의 경우, 생성자의 함수 몸체에서 초기화할 수 없습니다.

이니셜라이저를 사용하면 const멤버 변수또한 초기화할 수 있습니다.

 

3. 참조 멤버 초기화 : 참조 멤버 변수(reference member)는 선언과 동시에 초기화해줘야 합니다.

이니셜라이저를 사용하면 참조 멤버 변수를 초기화할 수 있습니다.

 

 

 

소멸자(Destructor)

모든 객체는 생성될 때 메모리에 올라간다.

소멸자는 객체 소멸 시(메모리에서 내려갈 때) 자동으로 호출되는 함수이다.

소멸자는 클래스 이름 앞에 물결표시~를 붙여서 정의하며, 반환 타입을 가지지 않는다.

class MyClass {
public:
    MyClass() {
        // 생성자 작업
    }

    ~MyClass() {
        // 소멸자 작업
    }
};

 

 

 

소멸자 특징

1. 객체가 소멸될 때(메모리가 내려갈 때) 자동으로 호출된다.

2. 클래스 내부에 매개변수가 없는 형태의 한 개의 소멸자만 정의할 수 있다

소멸자는 오버로딩 할 수 없다.

3. 메모리 해제나 자원 정리 등의 작업을 수행할 때 유용하다

객체에서 동적할당한 메모리는 소멸자에서 해제해주면 좋다.

 

 

반응형

 

반응형

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

템플릿  (0) 2023.05.30
참조자(Reference)  (0) 2023.05.30
네임스페이스(namespace)  (0) 2023.05.30
입출력  (0) 2023.05.30
객체에 대한 이해  (0) 2023.05.30
반응형
템플릿이란?

템플릿은 클래스나 함수를 일반화하여

재사용할 수 있도록 해주는 기능입니다.

 

템플릿을 통해 코드의 일부를 독립적으로 작성할 수 있으며,

이를 통해 일반적인 알고리즘 또는 자료 구조에

유연하게 적용할 수 있다.

 

 

 

클래스 템플릿

클래스 템플릿은 클래스를 정의하는 템플릿이다.

클래스 템플릿을 사용해 멤버 변수와 멤버 함수의 타입을

템플릿 매개변수로 지정한 일반화된 형태로 작성할 수 있다.

 

템플릿 매개변수는 클래스 내에서 사용되는 데이터 타입을 나타내며,

템플릿을 인스턴스화할 때 실제 타입으로 대체된다.

 

이렇게 생성된 클래스의 인스턴스는 지정된 타입에 맞게 동작하며,

동일한 코드를 다양한 타입에 대해 재사용가능하다.

 

 

 

 

함수 템플릿

함수 템플릿은 함수를 정의하는 템플릿이다.

함수 템플릿을 사용하면 함수의 매개변수와 반환되는 데이터 타입을

템플릿 매개변수로 지정하여 일반화된 형태로 작성 가능하다.

 

함수 템플릿을 인스턴스화할 때 실제 타입으로 대체되며,

해당 타입에 맞는 코드가 생성된다.

 

 

 

 

템플릿의 장점

템플릿을 사용하면 코드의 재사용성과 유연성을 높일 수 있다.

데이터 타입에 독립적인 알고리즘과 자료 구조를 만들어

다양한 타입에 대해 재사용 가능하며, 타입 오류를 컴파일 타임에

확인할 수 있는 강한 타입 검사도 가능하다.

템플릿은 C++의 강력한  기능 중 하나로,

제네릭 프로그래밍을 구현하는데 널리 활용된다.

 

아래의 코드는 템플릿의 예제이다.

// 클래스 템플릿
template <typename T>	// 템플릿 매개변수 T
class Pair {
private:
    T first;
    T second;

public:
    Pair(T f, T s) : first(f), second(s) {}

    T getFirst() const { return first; }
    T getSecond() const { return second; }
};

// 함수 템플릿
template <typename T>	// 템플릿 매개변수 T
T getMax(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    // 클래스 템플릿 사용 예제
    Pair<int> intPair(10, 20);
    std::cout << "First: " << intPair.getFirst() << ", Second: " << intPair.getSecond() << std::endl;

    Pair<std::string> stringPair("Hello", "World");
    std::cout << "First: " << stringPair.getFirst() << ", Second: " << stringPair.getSecond() << std::endl;

    // 함수 템플릿 사용 예제
    int num1 = 10, num2 = 20;
    std::cout << "Max: " << getMax(num1, num2) << std::endl;

    double num3 = 3.14, num4 = 2.71;
    std::cout << "Max: " << getMax(num3, num4) << std::endl;

    return 0;
}

 

반응형

 

반응형

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

생성자와 소멸자  (0) 2023.06.01
참조자(Reference)  (0) 2023.05.30
네임스페이스(namespace)  (0) 2023.05.30
입출력  (0) 2023.05.30
객체에 대한 이해  (0) 2023.05.30
반응형
참조자(Reference)

C++ 에서 참조자는 변수의 또 다른 이름을 제공하는 방법이다.

참조자는 기존 변수에 대한 별칭(alias)이며, 변수와 동일한 메모리 위치를 가리킨다.

참조자는 포인터와 유사한 개념이지만, 포인터와는 다른 동작 방식을 가진다.

 

참조자를 정의하려면 아래의 코드 처럼 데이터 타입& 변수명 = 변수; 를 사용하면 된다.

int num1 = 1020;	// num1주소 100번지

int& num2 = num1;	// num2주소 100번지

num2 = 3040;
	
cout << "VAL: " << num1 << endl;	// 3040
cout << "REF: " << num2 << endl;	// 3040

cout << "VAL: " << &num1 << endl;	// 100번지
cout << "REF: " << &num2 << endl;	// 100번지

 

참조자를 사용하면 변수에 대한 별칭을 생성하여 해당 변수에 직접 접근할 수 있다.

참조자는 변수에 대한 포인터로 생각할 수도 있지만, 결정적인 차이가 존재한다.

포인터는 널(null)값을 가질 수 있고, 포인터 변수를 다른 변수로 변경할 수 있다.

 

그러나 참조자는 반드시 초기화해야 하며, 한 번 참조된 변수를 다른 변수로 변경할 수 없다.

즉, 참조자는 항상 참조한 변수를 가리키게 된다.

 

레퍼런스는 메모리 공간을 공유하지만, 포인터는 새로운 메모리 공간을 할당받고,

그 공간에 주소를 참조하는 방식이다. 즉  레퍼런스 연산자는 할당되는 메모리 공간이

무조건 필요해서 선언과 동시에 초기화를 해줘야 한다.

 

아래의 코드처럼 널 값이 필요할 때는 포인터 연산자를 사용하고

널 값이 필요없는 경우는 레퍼런스연산자를 사용하면 된다.

int& num1;		// 컴파일 에러
int& num2 = NULL;	// 컴파일 에러
int* num3;		// 컴파일 성공
int* num4 = NULL;	//컴파일 성공

 

참조자는 함수의 매개변수로 사용될 때 특히 유용하다.

함수에 매개변수로 참조자를 사용하면 원본 변수에 대한 복사본을

생성하지 않고도 함수 내에서 변수를 수정할 수 있다.

함수 호출 시간과 메모리 사용을 절약할 수 있다.

 

 

 

 

참조자 활용

참조자는 C++에서 많은 곳에서 사용되며, 변수 별칭 생성, 함수 매개변수 전달,

연산자 오버로딩 등 다양한 상황에서 유용하다. 그러나 참조자는 주의해서 사용해야 한다.

참조자를 잘못 사용하면 예상하지 못한 동작이 발생할 수 있다.

 

 

 

참조자 주의사항

참조자는 선언과 동시에 초기화해줘야 하며, 그 이후에는 다른 변수로

변경이 불가능하다. 즉, 참조자는 참조한 변수를 계속 참조하게 된다.

 

아래의 코드는 이와 관련된 예제이다.

int x = 5;
int y = 10;
int& ref = x;

ref = y;  // x의 값이 10으로 변경됨

위의 코드는 ref참조자가 x의 메모리 공간을 공유하게 된다.

그 밑에서 ref에 y를 할당해준다. 이러면 ref참조자가 y의 메모리 공간을

공유할거라 생각할 수도 있지만, 실상은 ref가 참조하는 x의 메모리 공간에

y의 데이터 값을 할당해주는 꼴이 됩니다.

 

반응형
반응형

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

생성자와 소멸자  (0) 2023.06.01
템플릿  (0) 2023.05.30
네임스페이스(namespace)  (0) 2023.05.30
입출력  (0) 2023.05.30
객체에 대한 이해  (0) 2023.05.30
반응형
네임스페이스(namespace)란?

C++에서 네임스페이스(namespace)는 식별자들을 그룹화하여

충돌을 방지하고 코드의 모듈성을 촉진하는데 사용되는 기능입니다.

네임스페이스는 일반적으로 C++ 표준 라이브러리 및 사용자 정의

코드에서 사용됩니다.

 

네임스페이스는 전역 범위에서 이름 충돌을 방지하기 위해 사용된다.

여러 개의 라이브러리 또는 모듈을 사용할 때 각각에 동일한 이름의 함수,

클래스, 변수 등이 있는 경우 충돌이 발생할 수 있다. 네임스페이스는

이러한 충돌을 방지하기 위해 식별자들을 고유하게 만들어 준다.

 

 

 

네임스페이스 정의

네임스페이스의 정의는 아래의 코드와 같이 할 수 있다.

namespace MyNamespace // 네임스페이스 이름
{
    // 네임스페이스에 속하는 함수, 클래스, 변수 등 정의
    int myFunction();
    class MyClass {
        // 클래스 멤버 정의
    };
    // ...
}

 

 

 

네임스페이스 사용

네임스페이스 내에 있는 함수나 클래스에 접근하려면 아래의 코드처럼 사용 가능하다.

int result = MyNamespace::myFunction();		// 네임스페이스이름::함수명()
MyNamespace::MyClass obj;

 

 

 

네임스페이스 정리

네임스페이스는 전역에서 쓰듯이 사용가능합니다.

네임스페이스끼리는 함수나 그 안에 데이터를 공유하지 않습니다.

 

주로 라이브러리를 만들때 사용됩니다.

 

네임스페이스를 사용하여 함수, 클래스, 변수등을 그룹화하면 다른 네임스페이스와의 충돌을

피할 수 있습니다. 또한 여러 개의 네임스페이스를 중복선언이 가능하여 계층 구조를 만들 수도 있습니다.

 

같은 네임스페이스를 공유하면 그 네임스페이스의 함수안에 다른 함수를 쓸 때

네임스페이스 이름을 생략할 수 있습니다. 다른 네임스페이스 함수를 호출할 때는

네임스페이스 이름을 붙여야 합니다.

 

네임스페이스 함수를 정의 하는곳이나 구현하는 곳이나 네임스페이스 내부로 간주합니다.

 

네임스페이스는 typedef처럼 별칭을 사용할 수 있습니다.

namespace ABC = AAA::BBB::CCC; // 네임스페이스 중첩이 가능하며, 이렇게 별칭으로 사용가능

// 두개의 코드는 같다.
AAA::BBB::CCC::num1
ABC::num1

 

아래의 코드처럼 using namesapce 네임스페이스이름; 를 사용하면

네임스페이스 이름을 생략하고 직접 함수를 호출할 수 있다.

#include <iostream>

namespace MyNamespace 
{
    void myFunction() 
    {
        std::cout << "Hello from MyNamespace!" << std::endl;
    }
}

int main() 
{
    using namespace MyNamespace;	//using namesapce 네임스페이스이름
    
    myFunction(); // 네임스페이스 이름을 생략하고 짧게 사용
    
    return 0;
}

 

반응형

 

반응형

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

템플릿  (0) 2023.05.30
참조자(Reference)  (0) 2023.05.30
입출력  (0) 2023.05.30
객체에 대한 이해  (0) 2023.05.30
제네릭 프로그래밍  (0) 2023.05.30
반응형
C++ 입출력 라이브러리

C++언어에서의 입출력을 사용하기 위해서는 <iostream> 라이브러리를 사용해야 한다.

이 라이브러리에는 표준 입력과 표준 출력을 다루는 객체들이 정의되어 있다.

C++에서의 <iostream>은 C에서의 <stdio.h>와 같다.

#include <iostream>

 

 

 

표준 출력 : 기본적인 출력

C++에서 표준 출력은 'std::cout' 객체를 사용하여 데이터를 출력할 수 있다.

cout은 "character output"을 의미하며, 텍스트 데이터를 표준 출력 장치(콘솔 또는 터미널등)

에 출력하는데 사용됩니다.

 

std::cout 객체를 사용하여 데이터를 출력할 수 있다.

stream 출력연산자 '<<' 와 함께 사용된다.

'<<'연산자는 출력할 값을 'cout'객체에 전달한다.

 

C++에서의 출력은 C의 출력에 필요한 서식문자가 필요 없다.

C++은 강력한 정적 타입 언어로서, 변수의 타입이 컴파일 시간에 결정된다.

변수의 타입을 컴파일러가 알고 있기에 해당 타입에 맞는 출력 방식을 자동으로 선택한다.

그러한 이유로 서식 지정자를 사용할 필요가 없다.

이를 통해 코드가 더 안전하고 유연해지며, 타입 오류를 미리 방지 가능하다.

int num = 11;
std::cout << "C++ " << num << std::endl;

 

아래의 코드처럼 using namesapce std를 사용하면 std:: 를 생략할 수 있다.

using namespace std;
int num = 11;

cout << "C++ " << num << endl;

 

 

 

표준 출력 : 형식화된 출력

서식 지정자를 사용하여 출력 형식을 지정할 수 있다.

일반적으로 'std::cout' 객체와 'std::setw', 'std::setprecision', 'std::fixed'

등의 함수와 조합하여 사용한다. 

위의 함수들을 사용하려면 <iomanip> 헤더 파일을 사용해야 한다.

 

  • std::setw(n) : 필드 폭을 n으로 설정한다. 출력 데이터를 오른쪽 정렬하고 필요한 경우 공백 추가.
  • std::setprecision(n) : 부동 소수점 숫자의 소수점 이하 자릿수를 n으로 설정
  • std::setfill(c) : 빈 필드를 채우는 문자를 c로 설정
  • std::setiosflags(flags) : 출력 상태 플래그를 설정 예를 들어, flags에 std::ios:fixed를 넣으면 소수점 이하 자릴수를 고정할 수 있다.

 

 

표준 출력 : 문자열 출력

'std::cout'객체와 '<<' 연산자를 사용해 C스타일 문자열인 char형 배열,

C++문자열 클래스 std::string문자열을 출력할 수 있다.

 

 

 

 

표준 출력 : 특수 문자 출력

std::cout 객체와 이스케이프 시퀀스를 사용하여 특수 문자를 출력할 수 있다.

일반적인 이스케이프 시퀀스로는 '\n'(개행), '\t'(탭)등이 있다.

 

 

 

출력 버퍼

std::cout 은 출력을 처리하기 위해 출력 버퍼를 사용한다.

출력 버퍼에 출력 내용이 쌓이며, 버퍼가 가득 차거나 개행 문자를 만나면

버퍼의 내용이 터미널, 콘솔창에 출력된다.

버퍼를 비우기 위해 'std::endl' 이나 'std::flush'를 사용한다.

 

std::endl 과 std::flush는 모두 출력 버퍼를 비우는 목적으로 사용되지만,

동작 방식에 차이가 있다.

 

std::endl

  • 개행 문자('\n')를 출력하고, 출력 버퍼를 비운다.
  • 개행 문자를 출력하기에 출력 내용을 새로운 줄로 이동시킨다.
  • 출력 버퍼를 비우면서 개행을 수행하여 출력 내용을 보기 좋게 정리할 수 있다.

std::flush

  • 출력 버퍼를 비우는 역할만 수행
  • 출력 버퍼를 비우고, 출력한 내용을 즉시 출력 장치에 표시
  • 개행 문자를 출력하지 않고, 출력 내용을 현재 줄에 유지
  • 즉각적인 출력을 위해 사용되며, 버퍼에 저장된 데이터를 즉시 표시할 때 유용

 

 

표준 입력 : 기본적인 입력

C++에서 표준 입력은 'std::cin' 객체를 사용하여 처리됩니다.

cin은 "character input"을 의미하며, 키보드를 통해서 데이터를 입력받습니다.

 

std::cin 객체를 사용하여 사용자로부터 데이터를 입력받는다.

stream 입력연산자 '>>'와 함께 사용된다.

'>>' 연산자는 입력 값을 변수에 할당합니다.

 

cin 객체는 공백 문자(스페이스, 탭, 엔터)를 기준으로 입력을 구분받는다.

사용자가 키보드로 엔터키를 누르면 입력된 문자열은 버퍼에 저장되며

cin을 통해 가져올 수 있다. C에서는 call by reference가 없어서

scanf를 사용할 때 포인터형으로 입력값을 받지만,

C++에서는 call by reference가 있어서 cin를 사용할 때

레퍼런스로 값을 받는다.

 

C 입력에서는 서식문자 또한 받지만, C++ 입력에서는 변수명만

아래의 코드에서처럼 넣어주면 된다.

int num;

scanf("%d", &num);		// C 입력방식
std::cin >> num >> std::endl;	// C++ 입력방식

 

 

 

입력 값에 대한 변수의 유효성

입력 값을 변수에 할당하기 전에 변수의 유효성을 확인하는 것이 좋다.

"변수의 유효성을 확인한다"는 것은 값을 변수에 할당하기 전에 해당 변수가

유효한 값인지를 확인하는걸 의미한다.

입력 값이 변수의 예상 범위를 벗어나거나 유효하지 않은 형식을 가질 경우,

'std::cin' 은 입력을 실패하고, 입력 버퍼에 잘못된 값이 남게 됩니다.

 

아래의 코드처럼 변수가 int형이지만 char형이나 double형을 넣을 경우가 이에 해당합니다.

int num
std::cin >> num;	// 'A' or '3.14' 입력

 

'std::cin.fail()'함수를 사용하여 입력이 실패했는지 확인 가능하다.

입력이 실패한 경우에 해당 변수를 올바른 값으로 설정하거나 예외 처리를 할 수 있다.

입력 버퍼에 잘못된 값이 남아있을 수 있어서 이를 비우기 위한'std::cin.clear()' 와

'std::cin.ignore()' 함수를 아래의 코드처럼 사용할 수 있다.

int num;
std::cin >> num;

if (std::cin.fail()) {
    std::cout << "올바른 입력이 아닙니다." << std::endl;
    std::cin.clear();  // 오류 플래그 초기화
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // 입력 버퍼 비우기
}

 

 

 

표준 입력 : 문자열 입력

'std::cin'객체와 'std::getline()'함수를 사용하여 문자열을 입력받을 수 있다.

'std::getline()' 함수를 사용하면 공백을 포함한 한 줄의 문자열을 입력받을 수 있다.

 

 

 

입력 버퍼

'std::cin' 객체를 사용하여 입력을 받을 때, 입력 버퍼에는 개행 문자(Enter 키로 인해 생성되는)나

공백등이 남을 수 있다. 그러한 입력 버퍼에 남은 문자를 제거하기 위해

'std::cin.ignore()' 함수를 사용하거나 'std::cin' 객체를 사용하거나 std::getline() 함수를

사용하여 입력 버퍼를 비울 수 있다.

 

 

 

입출력함수 주의사항

1. 입력 버퍼 청소: 

사용자로부터 입력을 받을때, 입력 버퍼에 개행 문자나 공백 등이 남을 수 있다.

이러한 남은 문자들은 의도치 않은 동작을 하게 만든다.

입력 버퍼에 남은 문자를 제거하기 위해 std::cin.ignore() 함수를 사용하거나

std::cin 객체를 사용하거나 std::getline()함수를 사용해 입력 버퍼를 비울 수 있다.

 

2. 변수 유효성 확인:

입출력 함수를 사용하여 값을 입력받을 때, 입력된 값이 변수의 범위를 벗어나거나

유효하지 않은 형식일 수 있다. 입력 값을 사용하기 전에 유효성을 확인하고,

필요에 따라 예외 처리를 수행해야 한다.

 

3 파일 입출력:

파일 입출력을 사용할 때는 파일을 성공적으로 열었는지 확인해야 한다.

파일이 성공적으로 열리지 않은 경우, 해당 파일에 대한 작업은 수행되지 않으므로

예외처리가 반드시 필요하다. 파일 작업이 완료되면, 파일을 꼭 닫아야 한다.

 

4 입력 값의 크기와 형식:

입력받는 값의 크기가 변수의 크기를 초과하거나 형식이 일치하지 않을 경우,

의도치 않은 동작이 발생할 수 있다.

변수의 크기에 맞게 입력을 받거나 형식 변환을 통해 올바른 값을 처리해야 한다.

 

반응형

 

반응형

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

참조자(Reference)  (0) 2023.05.30
네임스페이스(namespace)  (0) 2023.05.30
객체에 대한 이해  (0) 2023.05.30
제네릭 프로그래밍  (0) 2023.05.30
함수 오버로딩(Function Overloading) & 함수 오버라이딩(Function Overriding)  (0) 2023.05.30

+ Recent posts