본문 바로가기
대외활동/시스템프로그래밍

시험대비 c++ 복습

by hoshi03 2024. 8. 25.

• 디폴트 매개변수

메서드 선언할때 기본 값을 미리 넣어두는 방식

a = 5, b= 5 형태로 a,b값을 둘다 미리 넣어두었다

b만 디폴트 값을 지정하는 방식은 가능하지만

a만 지정해두는 식으로는 사용 불가능하다

void star(int a  = 5, int b = 5) {
    cout << a << " " << b;
    cout << '\n';
}


int main() {
    star(10, 10);
    star(10);
    star();
    return 0;
}

 

• friend 키워드

외부 함수나 멤버함수, 클래스를 프렌드로 선언하면 자유롭게 접근할 수 있다

class Test{
    int a = 5;
    int b = 10;
public:
    friend void show(Test t);
    Test(int a, int b){
        this->a = a;
        this->b = b;
    }
    
    Test(){};
};

void show(Test t){
    cout << "a : " << t.a << " b : " << t.b << '\n';
}

int main() {
    Test test1;
    Test test2(3,3);
    show(test1);
    show(test2);
}

 

• 접근 지정자

private - 클래스 내의 멤버만 접근 가능

public - 자유롭게 접근

protected - 클래스 내의 멤버 + 상속받은 멤버만 접근

c++에서 디폴트 접근 지정은 private로 처리된다

 

• copy 메서드

스택 크기를 재지정할때 

copy(복사할 배열 시작주소(이름), 복사할 끝 위치, 새로 저장할 배열 시작주소(이름)); 형태의 메서드를 사용

int Stack::setSize(int n) {

	int* tmp = new int[n];

	if (n < getSize()) {
		copy(arr, arr + n, tmp);
		if (getTop() >= n) top = n - 1;
	}
	else copy(arr, arr + getSize(), tmp);

	delete[] arr;
	arr = tmp;
	size = n;

	return size;
}

 

• 동적 할당

 

자료형 * 이름 = new 자료형 이름;형태

동적으로 할당한걸 delete 메서드를 사용해서 해제

    int n;
    cin >> n;
    int* arr = new int[n];
    for (int i = 0; i < n; i++) {
        arr[i] = i+1;
        cout << arr[i] << " ";
    }
    delete[] arr;

 

• 연산자 오버로딩

 

클래스 내부에 연산자 메서드를 선언한다

int operator+(Rectangle& obj) 형태

 

int Rectangle :: operator+(Rectangle& obj) {
    int tmp = 0;
    tmp += this->getArea();
    tmp += obj.getArea();
    return tmp;
}

bool Rectangle :: operator==(Rectangle& obj) {
    if (this->getArea() == obj.getArea()) return true;
    return false;
}

Rectangle& Rectangle :: operator+=(Rectangle& obj) {
    this->width += obj.width;
    return *this;
}

 

클래스 내부에 정의한 연산자 오버로딩 메서드는  a+b시 this가 왼쪽 피연산자, obj는 뒤에 있는 클래스 객체가 된다

 

- 전위 연산자 오버로딩, << 연산자 오버로딩

#include <iostream>
using namespace std;

class Power{
    int kick;
    int punch;

public:
    Power(int kick = 0, int punch = 0){
        this->kick = kick;
        this->punch = punch;
    }

    void show(){
        cout << "kick : " << kick << " punch : " << punch << '\n';
    };

    Power& operator ++ ();
    Power& operator << (int n);
    Power& operator ++ (int);
};

// 단항 ++ 연산자
Power& Power::operator++() {
    kick++;
    punch++;
    return *this;
}

// << 연산자
Power &Power::operator<<(int n) {
    kick+= n;
    punch += n;
    return *this;
}

Power &Power::operator++(int) {
    kick++;
    punch++;
    return *this;
}

int main(){
    Power a(3,5);

    a.show();
    ++a;
    a.show();
    a << 3 << 4;
    a.show();
    a++;
    a.show();
}

 

 

• 상속

 

업캐스팅, 다운캐스팅은 알거라고 믿고 패스

 

-가상 상속 

자식 : virtual 부모

형태로 사용하는 이유  다중 상속시 모호성이 발생할 수 있는데 가상 상속을 받으면 상위 클래스의 멤버가 이미 상속되어 있으면 이미 할당된 멤버를 공유하게 된다

 

-멤버 초기화 리스트

멤버 초기화 리스트를 사용하면 멤버 초기화와 할당이 동시에 되서 성능에서 이점이 있고

const 멤버의 경우에는 멤버 초기화 리스트를 사용해야 값을 지정해둘 수 있다

#include <iostream>
#include <string>

class Person {
private:
    std::string name;
    int age;

public:
    // 멤버 초기화 리스트를 사용하는 생성자
    Person(std::string name, int age) : name(name), age(age) {
        // 생성자 본문이 비어있어도 멤버 초기화는 멤버 초기화 리스트에서 이미 완료되었습니다.
    }

    void printInfo() const {
        std::cout << "Name: " << name << ", Age: " << age << std::endl;
    }
};

int main() {
    // 객체 생성 시 생성자에 인자를 전달
    Person person("Alice", 30);
    person.printInfo();

    return 0;
}

 

- 템플릿 클래스

template <class T>

사용할 템플릿 변수 명을 지정해두고 해당 타입을 넣으면서 사용

템플릿 클래스의 경우에는 클래스명<T>::메서드

형태로 구현부 작성

 

- 람다식

 

[]() { 메서드}  형태로 사용, auto 람다식명 = 람다식 형태로 저장 가능

auto sum = [](int x, int y){cout << x+y << '\n';};
sum(3,5);

 

-람다식에 캡쳐 리스트에 외부의 값을 전달해서 외부의 값을 변경하는 식으로 사용할 수 있다

int res = 0;
auto sum = [&res](int x, int y){res = x+y;};
sum(3,5);
cout << res <<'\n';
sum(5,10);
cout << res <<'\n';

 

- for_each 구문에서 실행할 메서드로 람다식을 넣을 수 있다

vector<int> v = {1, 2, 3, 4, 5};
for_each(v.begin(), v.end(), [](int n){ cout << n << " ";});

 

 

 

- 입출력

ifstream - 읽기

ifstream inputFile("data.txt");
if (!inputFile) {
    cerr << "Error opening file for reading!" << endl;
    return 1;
}

int intValue;
double doubleValue;
string stringValue;

inputFile >> intValue >> doubleValue;  // int와 double 값을 읽어옵니다.
inputFile.ignore();  // 줄바꿈 문자나 공백을 무시합니다.
getline(inputFile, stringValue);  // 나머지 줄을 문자열로 읽어옵니다.

inputFile.close();

// 읽은 데이터를 출력합니다.
cout << "Integer value: " << intValue << endl;
cout << "Double value: " << doubleValue << endl;
cout << "String value: " << stringValue << endl;

ofstream - 쓰기

ofstream outputFile("data.txt");
if (!outputFile) {
    cerr << "Error opening file for writing!" << endl;
    return 1;
}
outputFile << 42 << " " << 3.14 << " " << "Hello World" << endl;
outputFile.close();
ofstream fout("test.txt", ios::app);

덮어씌우지 않고 추가로 작성하려면 fout의 인자로 ios::app을 추가한다

 

먼저 test.txt 파일을 열어서 데이터를 쓰고  그 다음 다시 읽어오는 코드

int main() {
    ofstream fout("test.txt");
    if (!fout) return 0;
    char tel[100], name[100];
    cin >> tel >> name;
    fout << tel << '\n' << name << '\n;
    fout.close();
    
    ifstream fin("test.txt");
    if (!fin) return 0;
    tel[100] = {}, name[100] = {};
    fin >> tel >> name;
    fin.close();
    cout << tel << '\n' << name;
}

 

 

 

'대외활동 > 시스템프로그래밍' 카테고리의 다른 글

0826 리눅스 시스템 프로그래밍  (0) 2024.08.26
시험대비 qt c++ 복습  (0) 2024.08.25
시험대비 C 복습  (0) 2024.08.23
라이브러리  (0) 2024.08.22
0822 gdb, core, valgrind  (0) 2024.08.22