IT 프로그래밍/객체지향프로그래밍

동적 객체 생성 new 연산자

기술1 2024. 6. 16. 14:18
반응형

 지금까지 데이터는 항상 이름이 가진 객체에 저장을 하였습니다. 하지만 C++에서는 NEW 연산자로 이름이 없는 객체를 생성할 수 있습니다. 이름이 없으면 그 객체를 어떻게 사용할까요?

 

NEW 연산자

이름이 없는 대신 new 연산자는 생성된 객체의 주소를 반환합니다.그 주소를 포인터에 저장하여 간접참조를 통해 객체를 사용할 수 있습니다.

 

일반적으로 동적 생성된 객체는 메모리에서 힙이라고 부르는 영역에 저장됩니다. 동적으로 생성된 객체는 명시적으로 delete해주지 않으면 자동 삭제되지 않습니다. 

해당 구조로 데이터가 컴퓨터에 저장되어 있습니다. Data section에는 전역변수들이 저장됩니다. 전역변수는 지역변수와는 달리 프로그램이 시작되는 시점에 데이터가 생성되고 완전히 종료될 때까지 유지하고 있는 변수를 의미합니다. 

 

그 다음 Stack에는 지역변수들이 저장되는 공간입니다. 지역변수가 정의되어 있는 함수가 호출될 때 생성되었다가 그 함수가 종료되면 즉시 소멸됩니다. 

 

Heap은 동적으로 생성된 객체들만 존재하는 공간입니다. 별개의 영역이라고 볼 수 있습니다.

 

int p;
int* pi = new int;
int* pi2 = new int(3);

이 객체들은 이름이 업습니다. 동적 개체로 생성된 주소를 반환해주기 때문에 발고 포인터 변수에 저장할 수 있는 것입니다. 그러면 이 동적 생성된 이름없는 객체를 저장하게 됩니다. 그러면 포인터에 간접참조 연산자로 할 수 있는 것입니다. 

 

객체를 생성하면서 원하는 값으로 초기화해주고 싶으면 new int(3)으로 해주면 3으로 생성된 객체가 생성이 되며 pi2라는 변수형 포인터로 변환을 하는 것입니다. 

클래스 객체나 배열을 동적으로 생성하는 것이 동적 생성의 일반적인 상황입니다. 

 

Term t(2, 3);
Term s = t;
Term* pterm = new Term(3, 4);
Term* q = pterm;

이렇게 t, s 객체가 생성이 됩니다. 그치만 이름이 없는 Term을 동적 생성할 수 있는 것입니다. 저런 식으로 Term* pterm = new Term(3, 4);로 해주면 저렇게 이름이 없는 동적 생성된 Term 객체를 생성을 하는 것입니다. 

 

q가 pterm을 =로 받는데 이것은 pterm이가리키는 주소를 받는 것이기 떄문에 new Term을 할당받게 됩니다. 

 

모든 사각형을 다 포함하는 사각형

#include <iostream>
using namespace std;

class MyPoint {
public:
	double x, y;
	MyPoint() = default;
	MyPoint(double a, double b) : x(a), y(b) {}
};

 

class MyRectangle {
private:
	MyPoint* lu;
	double width, height;
public:
	MyRectangle() = default;
	MyRectangle(MyPoint* p, double w, double h) : lu(p), width(w), height(h) {}
	MyRectangle(double x, double y, double w, double h) :
		lu(new MyPoint(x, y)), width(w), height(h) {}


	double xmin() { return lu->x; }
	double xmax() { return lu->x+height; }
	double ymin() { return lu->y; }
	double ymax() { return lu->y + width; }
};

lu가 포인터이기 때문에 lu->x 로 해줘야 합니다. 

 

int main() {
	vector<MyRectangle*> rects;
	int n;
	double x, y, w, h;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> x >> y >> w >> h;
		MyRectangle* r = new MyRectangle(x, y, w, h);
		rects.push_back(r);
	}
}

MyRectangle 타입의 포인터들의 벡터입니다.

 

MyRectangle 객체들을 동적생성하고 그 주소를 벡터 rects에 저장합니다. 

	double min_x = rects.at(0)->xmin();
	double max_x = rects.at(0)->xmax();
	double min_y = rects.at(0)->ymin();
	double max_y = rects.at(0)->ymax();

	for (auto r : rects) {
		if (r->xmin() < min_x) min_x = r->xmin();
		if (r->xmax() < max_x) max_x = r->xmax();
		if (r->ymin() < min_y) min_y = r->ymin();
		if (r->ymin() < max_y) max_y = r->ymax();
	}
	cout << min_x << " " << min_y << " " << max_y - min_y
		<< " " << max_x - min_x << endl;

이렇게 min_max가 나오면 바꿔주도록 한 다음 출력을 하는 것입니다.

 

전체 코드

#include <iostream>
#include <vector>
using namespace std;

class MyPoint {
public:
	double x, y;
	MyPoint() = default;
	MyPoint(double a, double b) : x(a), y(b) {}
};

class MyRectangle {
private:
	MyPoint* lu;
	double width, height;
public:
	MyRectangle() = default;
	MyRectangle(MyPoint* p, double w, double h) : lu(p), width(w), height(h) {}
	MyRectangle(double x, double y, double w, double h) :
		lu(new MyPoint(x, y)), width(w), height(h) {}


	double xmin() { return lu->x; }
	double xmax() { return lu->x+height; }
	double ymin() { return lu->y; }
	double ymax() { return lu->y + width; }
};

int main() {
	vector<MyRectangle*> rects;
	int n;
	double x, y, w, h;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> x >> y >> w >> h;
		MyRectangle* r = new MyRectangle(x, y, w, h);
		rects.push_back(r);
	}

	double min_x = rects.at(0)->xmin();
	double max_x = rects.at(0)->xmax();
	double min_y = rects.at(0)->ymin();
	double max_y = rects.at(0)->ymax();

	for (auto r : rects) {
		if (r->xmin() < min_x) min_x = r->xmin();
		if (r->xmax() < max_x) max_x = r->xmax();
		if (r->ymin() < min_y) min_y = r->ymin();
		if (r->ymin() < max_y) max_y = r->ymax();
	}
	cout << min_x << " " << min_y << " " << max_y - min_y
		<< " " << max_x - min_x << endl;
}
class MyRectangle {
private:
    MyPoint* lu;
    double width, height;
public:
    MyRectangle() = default;
    MyRectangle(MyPoint* p, double w, double h) : lu(p), width(w), height(h) {}
    MyRectangle(double x, double y, double w, double h) :
        lu(new MyPoint(x, y)), width(w), height(h) {}

    double xmin() { return lu->x; }
    double xmax() { return lu->x + width; }
    double ymin() { return lu->y; }
    double ymax() { return lu->y + height; }
};

int main() {
    vector<MyRectangle*> rects;
    int n;
    double x, y, w, h;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> x >> y >> w >> h;
        MyRectangle* r = new MyRectangle(x, y, w, h);
        rects.push_back(r);
    }

    double min_x = rects.at(0)->xmin();
    double max_x = rects.at(0)->xmax();
    double min_y = rects.at(0)->ymin();
    double max_y = rects.at(0)->ymax();

    for (auto r : rects) {
        if (r->xmin() < min_x) min_x = r->xmin();
        if (r->xmax() > max_x) max_x = r->xmax();
        if (r->ymin() < min_y) min_y = r->ymin();
        if (r->ymax() > max_y) max_y = r->ymax();
    }
    cout << min_x << " " << min_y << " " << max_y

코드 설명
클래스 정의

MyPoint 클래스:
이 클래스는 2D 공간에서 점을 나타냅니다. 
𝑥
x와 
𝑦
y 좌표를 가집니다.
기본 생성자와 
𝑥
x와 
𝑦
y 좌표를 초기화하는 생성자를 가지고 있습니다.

 

MyRectangle 클래스:
이 클래스는 직사각형을 나타내며, 왼쪽 위 모서리 점(MyPoint 객체), 너비, 높이로 정의됩니다.
MyPoint 포인터를 사용하여 직사각형을 초기화하는 생성자와 좌표를 직접 사용하는 생성자를 가지고 있습니다.
직사각형의 최소 및 최대 
𝑥
x와 
𝑦
y 좌표를 반환하는 메서드를 제공합니다.

 

메인 함수

메인 함수는 표준 입력으로부터 직사각형의 수와 각 직사각형의 속성(왼쪽 위 모서리의 
𝑥
,
𝑦
x,y 좌표, 너비, 높이)을 입력받습니다.
입력받은 속성으로 MyRectangle 객체를 생성하고, 그 객체들을 벡터에 저장합니다.

 

첫 번째 직사각형을 기준으로 최소 
𝑥
x값, 최대 
𝑥
x값, 최소 
𝑦
y값, 최대 
𝑦
y값을 초기화합니다.
모든 직사각형을 순회하며 최소 
𝑥
x값과 최대 
𝑥
x값, 최소 
𝑦
y값과 최대 
𝑦
y값을 갱신합니다

반응형