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

객체지향프로그래밍 그룹액티비티5

기술1 2024. 6. 8. 15:51

그룹 액티비티 1번

class myClass
{
	int pra = 5;
public:
	int pub = 10;
	void set_pr(int x) { pra = x; }
	void set_pu(int x) { pub = x; }
};

int main() {
	myClass m;
	int a, b;
	a = m.pra;
	b = m.pub;
	m.set_pr(100);
	m.set_pu(200);
	return 0;
}

pra가 private로 선언되어 있습니다. private로 선언되어 있을 경우 클래스 외부에서 직접 접근할 수 없기 대문에 오류가 나옵니다.

 

이런 경우 public으로 처리를 해서 해야합니다. 아니면 public에 get_pr() 함수를 생성해서 처리해줘도 됩니다.

 

class myClass
{
	int pra = 5;
public:
	int pub = 10;
	void set_pr(int x) { pra = x; }
	void set_pu(int x) { pub = x; }
	int get_pr() const { return pra; }
};

int main() {
	myClass m;
	int a, b;
	a = m.get_pr();
	b = m.pub;
	m.set_pr(100);
	m.set_pu(200);
	return 0;
}

 

그룹액티비티 1-2

class Box
{
	int capacity;
	Box() {}
	Box(double capacity) {
		this->capacity = capacity;
	}
};

int main()
{
	Box b1(10);
	Box b2 = Box(14);
	return 0;
}

해당 함수의 경우 생성자의 접근 제어 문제가 발생합니다. 기본 생성자 Box() 가 private로 선언되어 있어 외부에서 객체를 생성할 수 없습니다. 클래스 내부에서 기본 생성자가 private로 선언되었기 때문에 Box b1(10); 및 Box b2 = Box(14)를 사용할 때 기본 생성자가 호출될 수 없습니다. 

 

생성자의 인수 타입도 int로 바꿔주면 좋습니다.

 

class Box
{
private:
	int capacity;
public:
	Box() {}
	Box(double capacity) {
		this->capacity = capacity;
	}

	void display() const { // 디버깅용 멤버 함수 추가
		std::cout << "Capacity: " << capacity << std::endl;
	}
};

int main()
{
	Box b1(10);
	Box b2 = Box(14);


	// 디버깅용 출력
	b1.display();
	b2.display();

	return 0;
}

 

그룹 액티비티 1-3번

class A {
public:
	static int a;
	void show() {
		a++;
		cout << "a: " << a << endl;
	}
};

int A::a = 5;

int main()
{
	A a, b;
	a.show();
	cout << A::a << endl;
	b.a = 10;
	cout << a.a << endl;
	return 0;
}

a: 6
6
10

이렇게 결과값이 나오게 됩니다. 

 

A a, b; : 'A' 클래스의 인스턴스 'a' 와 'b'를 생성합니다. 이때, 정적 멤버 변수 'a'는 클래스의 모든 인스턴스 값을 공유합니다. a.show() 같은 경우 'a'의 값을 1을 증가시킨 다음 6을 출력합니다.

 

이후 정적 멤버 변수 'a'를 출력하는데 A::a는 6이므로 6이 출력됩니다. 

 

b.a = 10; 을 통해 인스턴스 b로 인해 정적 멤버 변수 'a'를 10으로 설정합니다. 이후 cout << a.a. << endl을 통해 인스턴스 'a'를 통해 a의 값이 출력되고 이는 10이 출력됩니다. 

 

요약

  • 정적 멤버 변수 a는 클래스 A의 모든 인스턴스가 공유합니다.
  • show 함수는 a의 값을 1 증가시키고 출력합니다.
  • 인스턴스 b를 통해 a의 값을 10으로 설정하면, 모든 인스턴스가 공유하는 a의 값도 변경됩니다.
  • 따라서, 마지막 출력에서는 a.a가 10이 됩니다.

객체지향프로그래밍 1-4

#include <iostream>
#include <algorithm>

using namespace std;

class A {
	int a = 0;
public:
	A() {
		cout << "Object of A is created\n";
	}
	void show() {
		a++;
		cout << "a: " << a << endl;
	}
};

int main()
{
	A a1, a2;
	A a3 = a1 + a2;
	return 0;
}

위 클래스의 경우 클래스 A의 객체를 생성하고 객체들끼리 덧셈 연산을 시도하지만 연산자 오버로딩이 구현되지 않아 컴파일 오류가 발생합니다.  각 부분의 역할과 발생하는 문제는 클래스 A에 operator + 연산자가 되어있지 않았기 때문에 오류가 발생합니다.

#include <iostream>
#include <algorithm>

using namespace std;

class A {
	int a = 0;
public:
	A() {
		cout << "Object of A is created\n";
	}
	A(int value) : a(value) {}
	void show() {
		a++;
		cout << "a: " << a << endl;
	}
	A operator+(const A& other) const {
		return A(a + other.a);
	}
};

int main()
{
	A a1, a2;
	A a3 = a1 + a2;
	return 0;
}

 

생성자 후 operator+를 구현해주었습니다. 

#include <iostream>
using namespace std;

class A {
	int a = 0;
public:
	A() {
		cout << "Object of A is created\n";
	}
	A(int value) : a(value) {}
	void show() {
		a++;
		cout << "a: " << a << endl;
	}
	A operator+(const A& other) const {
		return A(a + other.a);
	}
	A operator-(const A& other) const {
		return A(a - other.a);
	}
	A operator*(const A& other) const {
		return A(a * other.a);
	}
	A operator/(const A& other) const {
		if (other.a == 0) {
			cout << "Division by zero error!" << endl;
			return A(0);
		}
		return A(a / other.a);
	}
	bool operator==(const A& other) const {
		return a == other.a;
	}
	bool operator!=(const A& other) const {
		return a != other.a;
	}
	void display() const {
		cout << "a: " << a << endl;
	}
};

int main()
{
	A a1(10), a2(2);
	A a3 = a1 + a2;
	a3.display(); // a: 12

	A a4 = a1 - a2;
	a4.display(); // a: 8

	A a5 = a1 * a2;
	a5.display(); // a: 20

	A a6 = a1 / a2;
	a6.display(); // a: 5

	if (a1 == a2) {
		cout << "a1 is equal to a2" << endl;
	} else {
		cout << "a1 is not equal to a2" << endl;
	}

	if (a1 != a2) {
		cout << "a1 is not equal to a2" << endl;
	} else {
		cout << "a1 is equal to a2" << endl;
	}

	return 0;
}

예상 문제를 대비한 다른 operator를 구현하였습니다. 

 

객체지향프로그래밍 1-5

#include <iostream>
#include <algorithm>

using namespace std;

class A {
	int a;
public:
	void show()
	{
		a++;
		cout << "a: " << a << endl;
	}
	void operator.() {
		cout << "operator . called\n";
	}
};

int main() {
	A a1, a2;
	return 0; 
}

operator. 을 오버로딩을 시도하고 있습니다. c++에서는 .을 오버로딩 할 수 없습니다. 다른 연산자를 오버로딩 하거나 이 코드에서 연산자 오버로딩을 제거해야 합니다. 

 

#include <iostream>
using namespace std;

class A {
	int a = 0; // 초기값 설정
public:
	void show() {
		a++;
		cout << "a: " << a << endl;
	}
	void operator()() {
		cout << "operator() called\n";
	}
};

int main() {
	A a1, a2;
	a1(); // operator() 호출
	a2(); // operator() 호출
	a1.show();
	a2.show();
	return 0; 
}

 

객체지향프로그래밍 1-6

#include <iostream>
#include <algorithm>

using namespace std;

class Point {
private:
	int x, y;
public:
	Point() : x(0), y(0) {}
	Point& operator()(int dx, int dy);
	void show() {
		cout << "x = " << x << ", y = " << y;
	}
};

Point& Point::operator()(int dx, int dy)
{
	x = dx;
	y = dy;
	return *this;
}

int main()
{
	Point pt;
	pt(3, 2);
	pt.show();
	return 0;
}

결과값 :  x = 3, y = 2;

 

주어진 코드는 Point 클래스를 정의하여 함수 호출 연산자 operator()를 오버로딩하여 객체가 함수처럼 호출될 때 x와 y 값을 설정하도록 하는 예제입니다. 

 

Point 클래스의 멤버 변수 x와 y를 정의한 다음 Point() : x(0), y(0) {} 을 기본 생성자로 x와 y를 0으로 초기화합니다. 이후 Point& operator()(int dx, int dy);를 통해 함수 호출 연산자를 오버로딩하여 x와 y를 설정하는 함수를 선언합니다. 

 

객체지향프로그래밍 1-7

class complex {
	int i, j;
public:
	complex(int a, int b)
	{
		i = a;
		j = b;
	}
	complex operator+(complex c)
	{
		complex temp;
		temp.i = this->i + c.i;
		temp.j = this->j + c.j;
		return temp;
	}

	void show() {
		cout << "Complex Number: " << i
			<< " + i " << j << endl;
	}
};

int main()
{
	complex c1(1, 2);
	complex c2(3, 4);
	complex c3 = c1 + c2;
	c3.show();
	return 0;
}

complex의 클래스의 기본 생성자가 정의되지 않았기 때문에 오류가 발생합니다. complex 클래스는 인수를 받는 생성자만 정의되어 있기 때문에 기본 생성자가 없어서 operator+에서 임시 객체 temp를 생성할 수 없습니다. 

 

따라서 complex 클래스에서 매개변수가 없는 생성자를 사용할 수 있게 해야 합니다. 

#include <iostream>
#include <algorithm>

using namespace std;

class complex {
	int i, j;
public:
	complex() : i(0), j() {} // 기본생성자 추가
	complex(int a, int b)
	{
		i = a;
		j = b;
	}
	complex operator+(complex c)
	{
		complex temp;
		temp.i = this->i + c.i;
		temp.j = this->j + c.j;
		return temp;
	}

	void show() {
		cout << "Complex Number: " << i
			<< " + i " << j << endl;
	}
};

int main()
{
	complex c1(1, 2);
	complex c2(3, 4);
	complex c3 = c1 + c2;
	c3.show();
	return 0;
}

기본생성자는 i와 j를 0으로 초기화해줍니다. 이 생성자를 통해 operator+ 함수에서 임시 객체 temp를 생성할 수 있습니다.

 

주어진 코드에서 발생하는 문제는 complex 클래스가 기본 생성자(매개변수가 없는 생성자)를 가지고 있지 않기 때문에 발생합니다. 클래스에서 명시적으로 정의된 생성자가 있지만 그 중에서는 매개변수를 받는 생성자만 있습니다. 이러한 경우 컴파일러는 자동으로 기본 생성자를 생성하지 않습니다. 

 

그러나 operator+ 함수에서 임시 객체 temp를 생성할 때, 이 객체를 초기화할 기본 생성자가 필요합니다. 

 

객체지향프로그래밍 1-8 

class Box {
	int capacity;
public:
	Box() {}
	Box(double capacity) {
		this->capacity = capacity;
	}
	bool operator<(Box b) {
		return b.capacity < this->capacity ?
			true : false;
	}
};

int main()
{
	Box b1(10);
	Box b2 = Box(14);
	if (b1 < b2)
		cout << "B1's capacity is small";
	else
		cout << "B2's capacity is small";
	return 0;
}

오버로딩 수정

#include <iostream>
#include <algorithm>

using namespace std;

class Box {
	int capacity;
public:
	Box() {}
	Box(double capacity) {
		this->capacity = capacity;
	}
	// < 연산자 오버로딩
	bool operator<(const Box& b) const {
		return this->capacity < b.capacity;
	}
};

int main()
{
	Box b1(10);
	Box b2 = Box(14);
	if (b1 < b2)
		cout << "B1's capacity is small";
	else
		cout << "B2's capacity is small";
	return 0;
}