2023. 7. 9. 16:16ㆍAlgorithm/with C++
1. 구조체
구조체(struct)는 하나 이상의 변수를 그룹 지어서 새로운 자료형을 정의하는 것이다.
출처 : https://boycoding.tistory.com/183
가. struct와 class의 차이점
C++에서 클래스(class
)와 구조체(struct
)는 매우 유사한 방식으로 작동한다.
둘 다 데이터 필드와 메서드를 포함할 수 있으며, 이들을 하나의 단위로 묶는 방법을 제공한다.
C++에서는 구조체도 메서드를 포함할 수 있다.
또한 클래스와 구조체 모두 상속을 통해 기능을 확장하고 코드를 재사용할 수 있습니다.
클래스(Class) | 구조체(Struct) | |
---|---|---|
기본 접근 제한자 | Private | Public |
기본 상속 방식 | Private | Public |
데이터와 메서드 | 모두 가능 | 모두 가능 |
생성자 및 소멸자 | 사용 가능 | 사용 가능 |
상속 | 가능 | 가능 |
다형성 | 지원 | 지원 |
기본 접근 제한자와 기본 상속 방식에 차이점이 있다.
이러한 차이점에도 불구하고, C++에서 클래스와 구조체는 기본적으로 같은 방식으로 작동한다.
대부분의 개발자들은 일반적으로 데이터를 그룹화하는 데 구조체를 사용하고, 데이터와 함께 동작(메서드)을 그룹화하는 데 클래스를 사용하는 경향이 있다.
출처 : https://novemberfirst.tistory.com/32
2. 예제
#include<iostream>
#include<vector>
using namespace std;
struct Car{
int a, b;
double c, d, e;
};
void print(Car car){
cout << car.a << " " << car.b << " " << car.c << " " << car.d << " " << car.e << '\n';
}
int main(){
Car car = {1, 1, 1, 1, 1};
print(car);
vector<Car> sonata;
sonata.push_back({1, 2, 3, 4, 5});
sonata.push_back({1, 2, 3, 4, 6});
sonata.push_back({});
sonata.push_back({1, 3});
for(Car car : sonata){
print(car);
}
return 0;
}
/*
1 1 1 1 1
1 2 3 4 5
1 2 3 4 6
0 0 0 0 0
1 3 0 0 0
*/
Car car = {1, 1, 1, 1, 1};
: 구조체 생성하는 방법 중 하나.
가. 생성자(constructor)
struct S{
int x, y, z;
//Overloading
S(int X, int Y, int Z) : x(X), y(Y), z(Z) {}
S(){x=-1; y=-1; z=-1;}
};
class나 struct을 생성할 때 생성자를 사용하게 되면 객체생성과 동시에 멤버 변수의 초기화를 진행할 수 있기 때문에 초기값을 지정해 줄 때 사용하면 유용하다.
#include<iostream>
#include<vector>
using namespace std;
struct S{
int x, y, z;
//Overloading
S(int X, int Y, int Z) : x(X), y(Y), z(Z) {}
S(){x=-1; y=-1; z=-1;}
};
int main(){
vector<S> v;
v.push_back(S(1,2,3));
v.push_back(S(10,20,30));
v.push_back(S());
cout << "v[0] : " << v[0].x << " " << v[0].y << " " << v[0].z << endl;
cout << "v[1] : " << v[1].x << " " << v[1].y << " " << v[1].z << endl;
cout << "v[2] : " << v[2].x << " " << v[2].y << " " << v[2].z << endl;
return 0;
}
/*
v[0] : 1 2 3
v[1] : 10 20 30
v[2] : -1 -1 -1
*/
S()
,S(1,2,3)
: 생성자 사용.
나. 연산자 오버로딩
#include<iostream>
#include<vector>
using namespace std;
struct S{
int x, y, z;
//Overloading
S(int X, int Y, int Z) : x(X), y(Y), z(Z) {}
S(){x=-1; y=-1; z=-1;}
bool operator < (const S & a) const{
if(x== a.x){
if(y == a.y) return z < a.z;
return y < a.y;
}
return x < a.x;
}
};
int main(){
vector<S> v;
v.push_back(S(1,2,3));
v.push_back(S(10,20,30));
v.push_back(S());
cout << "v[0] : " << v[0].x << " " << v[0].y << " " << v[0].z << endl;
cout << "v[1] : " << v[1].x << " " << v[1].y << " " << v[1].z << endl;
cout << "v[2] : " << v[2].x << " " << v[2].y << " " << v[2].z << endl;
cout << "v[0]<v[1] : " << (v[0]<v[1]) << '\n' ;
return 0;
}
/*
v[0] : 1 2 3
v[1] : 10 20 30
v[2] : -1 -1 -1
v[0]<v[1] : 1
*/
연산자 오버로딩은 기존의 연산자들(+, - , % , / , >= , == , += , -=, ++, -- , []…)
을 오버로딩하여 자신만의 방식으로 연산자를 재정의하는 것이다.
struct Point{
int y, x;
Point(int y, int x) : y(y), x(x){}
Point(){y = -1; x = -1; }
bool operator < (const Point & a) const{
if(x == a.x) return y < a.y;
return x < a.x; }
};
<
연산자를 재정의 하고 있다.
Bool
: 반환하는 자료형operator <
: 연산자<
를 재정의 하겠다.(const Point & a)
: 매개변수const{…}
: 상수멤버함수로 객체(여기선 구조체)의 멤버 변수의 값을 변경할 수 없는 함수다.
연산자 오버로딩인 operator <
함수는 원래 const
로 만들고, 매개변수도 const
로 받는 것이 바람직합니다.
구조체를 값으로 받지 않고 주소로 받은 것.
구조체는 기본형 변수보다는 크기가 크다.
값으로 받으면 프로그램 속도가 느려진다.
속도를 높이기 위해 주소로 받는다.
그런데 주소로 받으면 operator <
함수가 구조체의 주소에 접근해 값을 변경할 수 있는 가능성이 있어 보안에 취약해진다.
const Point & a
처럼 읽기 전용으로 선언해 operator <
가 구조체의 값을 변경하지 못하도록 하는 것이다.
c++ 클래스에서 함수 헤더 뒷부분에 const
를 붙이는 함수를 상수멤버함수라고 합니다.
상수멤버함수는 객체의 멤버변수(여기선 a.x
, a.y
)를 읽기만 하지 값을 변경할 수 없는 함수다.
즉 둘 다 보안을 위해 const
를 붙이는 것이며, 연산자 오버로딩 함수가 const
로 작성된 것일 때만 에러 없이 작동을 합니다.
다. 구조체 정렬
#include<iostream>
#include<vector>
using namespace std;
struct Point{
int x, y;
};
bool cmp(const Point & a, const Point & b){
return a.y > b.y; //y값 기준 내림차순
}
vector<Point> v;
int main(){
for(int i = 10; i >= 1; i--){
v.push_back({i, 10-i});
}
sort(v.begin(), v.end(), cmp); //custom 비교 함수가 true이도록 정렬
for(auto i : v) cout << i.x << " : " << i.y << '\n';
return 0;
}
/*
1 : 9
2 : 8
3 : 7
4 : 6
5 : 5
6 : 4
7 : 3
8 : 2
9 : 1
10 : 0
*/
커스텀 비교함수를 사용해서 sort() 함수로 구조체를 쉽게 정렬할 수 있다.
'Algorithm > with C++' 카테고리의 다른 글
[C++] 순열 (0) | 2023.07.10 |
---|---|
[C++] call by value? reference? (0) | 2023.07.09 |
[C++] stack & queue & deque & priority_queue (0) | 2023.07.09 |
[C++] set & multiset (0) | 2023.07.09 |
[C++] map & unordered_map (0) | 2023.07.09 |