관리 메뉴

공부 기록장 💻

명품 C++ Programming 5장 실습 문제 - 참조 매개 변수, 참조 객체, 복사 생성자, 참조 리턴 본문

# Language & Tools/C++

명품 C++ Programming 5장 실습 문제 - 참조 매개 변수, 참조 객체, 복사 생성자, 참조 리턴

dream_for 2021. 4. 14. 18:31

(명품 C++ 프로그래밍 5장)

 

 

 

1. 

#include <iostream>
using namespace std;

class Circle {
	int radius;
public:
	Circle() :Circle(1) {}
	Circle(int r) { this->radius = r; }
	double getArea() { return 3.14 * radius * radius; }
	void setRadius(int r) { this->radius = r; }
	int getRadius() { return this->radius; }
};

void swap(Circle &c1, Circle &c2) {
	Circle tmp;

	tmp = c1;
	c1 = c2;
	c2 = tmp;
}
int main() {
	Circle c1(5);
	Circle c2(10);
	cout << "c1의 반지름 = " << c1.getRadius() << " 넓이 = " << c1.getArea() << endl;
	cout << "c2의 반지름 = " << c2.getRadius() << " 넓이 = " << c2.getArea() << endl;
	
	swap(c1, c2);
	cout << endl << "<swap 함수 호출 후>" << endl;

	cout << "c1의 반지름 = " << c1.getRadius() << " 넓이 = " << c1.getArea() << endl;
	cout << "c2의 반지름 = " << c2.getRadius() << " 넓이 = " << c2.getArea() << endl;
}

 

 

 

 

2.

#include <iostream>
using namespace std;

void half(double& num) { num /= 2; }
int main() {
	double n = 20;
	half(n);
	cout << n << endl;
}

 

 

3.

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

void combine(string& text1, string& text2, string& text3) {
	text3 = text1 +' '+ text2;
}
int main() {
	string text1("I love you"), text2("very much");
	string text3;
	combine(text1, text2, text3);
	cout << text3 << endl;
}

 

 

4.

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

bool bigger(int a, int b, int& big) {
	big = a > b ? a : b;
	return a == b;
}
int main() {
	int a, b, big;
	cout << "a와 b입력 : ";
	cin >> a >> b;
	
	if (bigger(a, b, big)) cout << "두 수는 같다 " << endl;
	else cout<< "큰 수는 " << big << endl;
}

 

 

5.

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


class Circle {
	int radius;
public:
	Circle(int r) { this->radius = r; }
	double getArea() { return 3.14 * radius * radius; }
	void setRadius(int r) { this->radius = r; }
	int getRadius() { return this->radius; }
	void show() { cout << "반지름이 " << radius << "인 원" << endl; }
};

// 바꾸고자 하는 원의 매개변수를 참조 매개변수로 변경하여 원본 객체의 멤버 값을 바꾼다.
void increaseBy(Circle &a, Circle b) {
	int r = a.getRadius() + b.getRadius();
	a.setRadius(r);
}
int main() {
	Circle x(10), y(5);
	increaseBy(x, y);
	x.show();
}

 

 

6. 

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

// 문자열 a에서 문자 c를 찾아 c 공간에 대한 참조를 리턴, 찾는다면 success를 true로 설정
char& find(char a[], char c, bool& success) {
	for (int i = 0;a[i] != NULL;i++) {
		if (a[i] == c) {
			success = true;
			return a[i];
		}
	}
}
int main() {
	char s[] = "Mike";
	bool b = false;
	char& loc = find(s, 'M', b); 
	if (b == false)
	{
		cout << "M을 발견할 수 없다 " << endl;
		return 0;
	}
	loc = 'S';
	cout << s << endl;
}

 

 

7.

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

class MyIntStack {
	int p[10];
	int tos; // 꼭대기를 가리키는 인덱스
public:
	MyIntStack() {
		tos = 0;
	}
	bool push(int n) { // 정수 n push. 꽉 차 있으면 false
		if (tos >9) return false;
		else {
			p[tos++] = n;
			return true;
		}
	}
	bool pop(int& n){ // pop 하여 n에 저장. 스택 비어있으면 false
		tos--;
		if (tos < 0)return false;
		else {
			n = p[tos];
			return true;
		}
	}
};
int main() {
	MyIntStack a;
	for (int i = 0;i < 11;i++) {
		if (a.push(i))cout << i << ' ';
		else cout << endl << i + 1 << " 번째 stack full" << endl;
	}
	int n;
	for (int i = 0;i < 11;i++) {
		if(a.pop(n)) cout<<n<<' ';
		else cout<<endl<<i+1<<" 번째 stack empty"<<endl;
	}
	cout << endl;
}

 

 

8. 

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

class MyIntStack {
	int* p; // 스택 메모리로 사용할 퐁니터
	int size; // 스택의 최대 크기
	int tos; // 스택의 탑을 가리키는 인덱스
public:
	MyIntStack();
	MyIntStack(int size) {
		this->size = size;
		p = new int[size];
		tos = 0;
	}
	MyIntStack(const MyIntStack& s) // 복사 생성자
	{
		//cout << "복사 생성자 b 실행" << endl;

		this->size = s.size;
		this->tos = s.tos;
		p = new int[s.size];
		for (int i = 0;i < s.tos;i++) {
			this->p[i] = s.p[i];
			// cout << this->p[i] << endl;
		}
	}
	~MyIntStack(){
		if (p)
			delete[]p; // p 메모리가 할당되어 있는 상태라면, 동적 할당된 메모리 반환한다.
	
	}
	bool push(int n) {
		if (tos > size) return false;
		else {
			p[tos++] = n;
			return true;
		}
	}
	bool pop(int& n) {
		if (tos < 0)return false;
		else {
			n = p[--tos];
			return true;
		}
	}
};
int main() {
	MyIntStack a(10); // 10개의 메모리 공간
	a.push(10); // 10을 푸시
	a.push(20); // 20을 푸시
	MyIntStack b = a; // 복사 생성 MyintStack b(a);
	b.push(30); // 30을 푸시

	int n;
	a.pop(n); // 스택 a에서 팝
	cout << "스택 a에서 팝한 값 " << n << endl;
	b.pop(n); // 스탹 b 팝
	cout << "스택 b에서 팝한 값 " << n << endl;
}

 

 

9. 자기 자신을 호출한 인스턴스(객체)를 반환

- 객체에 대한 참조를 하여, 자기 자신 객체를 반환하는 함수

 

this 포인터가 가리키는 값(자기 자신 객체) 반환

 

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

class Accumulator {
	int value;
public:
	Accumulator(int value) { this->value = value; };
	Accumulator& add(int n) { // value에 n을 더해 값을 누적; 
		this->value += n;
		//cout <<this<<endl;
		return *this;
	} 
	int get() { return value; }; // 누적된 값 value return
};
int main() {
	Accumulator acc(10);
	acc.add(5).add(6).add(7);
	cout << acc.get() << endl;;
}

 

10.

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

class Buffer {
	string text;
public:
	Buffer(string text) { this->text = text; }
	void add(string text) { this->text += text; }
	void print() { cout << text << endl; }
};

Buffer& append(Buffer& buf, string str) {
	buf.add(str);
	return buf;
}

int main() {
	Buffer buf("Hello");
	Buffer& temp = append(buf, "Guys"); // 객체와 string문자열 객체를 매개변수로 하여 얻는 참조 객체를 temp에 저장
	temp.print();
	buf.print();
}

 

 

11.

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

class Book {
	char* title;
	int price;
public:
	Book(const char* title, int price) {
		//cout << "생성자 실행" << endl;
		int len = strlen(title);
		this->title = new char[len + 1];
		strcpy(this->title, title);
		this->price = price;
	}
	Book(const Book& b) {
		//cout << "복사 생성자 실행" << endl;
		int len = strlen(b.title);
		this->title = new char[len+1];
		strcpy(this->title, b.title);
		this->price = b.price;
	}
	~Book() {
		if (this->title) {
			//cout << "동적 메모리 반환" << endl;
			delete[]title;
		}
	}
	void set(const char* title, int price) {
		//cout << "set 함수 실행" << endl;
		if (this->title) delete[] this->title; // 할당된 메모리가 있다면 반환한후
		int len = strlen(title); 
		this->title = new char[len + 1]; // 새로운 메모리 다시 할당
		strcpy(this->title, title);
		this->price = price;
	}
	void show() { cout << title << ' ' << price << "원" << endl; }
};

int main() {
	Book cpp("명품C++", 10000);
	Book java = cpp; // 복사 생성자 호출
	java.set("명품자바", 12000);
	cpp.show();
	java.show();
}

 

새로운 문자열로 title을 다시 설정하는 set()함수에 대하여,

이미 동적 할당된 title에 대한 메모리 공간을 반환하고,

새로 매개 변수로 전달된 title의 문자열 길이를 구하여 다시 새로운 메모리 공간을 동적 할당한다.

 

 

 

(4) string 객체를 사용하면 정말 편하다.

 

// 11번의 4번- string 문자열 객체 사용하기

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

class Book {
	string title;
	int price;
public:
	Book(string title, int price) {
		this->title = title;
		this->price = price;
	}
	// 복사 생성자 자동 실행
	void set(string title, int price) {
		//cout << "set 함수 실행" << endl;
		this->title = title;
		this->price = price;
	}
	void show() { cout << title << ' ' << price << "원" << endl; }
};

int main() {
	Book cpp("명품C++", 10000);
	Book java = cpp; // 복사 생성자 호출
	java.set("명품자바", 12000);
	cpp.show();
	java.show();
}

 

 

 

 

12. 

 

(1)

깊은 복사 생성자 작성

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

class Dept {
	int size;
	int* scores;
public:
	Dept(int size) {
		//cout << "기본 생성자 실행" << endl;
		this->size = size;
		scores = new int[size];
	}
	Dept(const Dept& dept){
		//cout << "복사 생성자 실헹" << endl;
		this->size = dept.size;
		this->scores = new int[dept.size];
		for (int i = 0;i < this->size;i++)
			scores[i] = dept.scores[i];
	}
	~Dept() {
		if (this->scores) {
			//cout << "동적 메모리 반환" << endl;
			delete[]scores;
		}
	}
	int getSize() {
		//cout << this->size << "개 사이즈" << endl;
	return this->size;
	}
	void read() {
		cout << size << "개 정수 입력 >> ";
		for (int i = 0;i < size;i++)
			cin >> scores[i];
	}
	bool isOver60(int index) {
		if (this->scores[index] > 60) {
			//cout << this->scores[index] << ' ' << endl;
			return true;
		}
		else {
			//cout << index<<"  :  "<<this->scores[index] << " under 60" << endl;
			return false;
		}
	}
};
int countPass(Dept dept) {
	int count = 0;
	for (int i = 0;i < dept.getSize();i++)
		if (dept.isOver60(i)) count++;
	return count;
}

int main() {
	Dept com(10); // size에 10 전달
	com.read(); // 10명 데이터 받아 scores에 저장
	int n = countPass(com);
	cout << "60점 이상은 " << n << "명" << endl;
}

 

 

(3)

복사 생성자를 주석 처리하여 실행되지 않게 함.

복사 생성을 실행하는 countPass 함수의 매개 변수를 참조 매개변수로 변경

 

// 원본 객체 변수 공간을 그대로 사용 (생성자, 소멸자 실행 X)

int countPass(Dept &dept) {
	int count = 0;
	for (int i = 0;i < dept.getSize();i++)
		if (dept.isOver60(i)) count++;
	return count;
}
#include <iostream>
#include <string>
using namespace std;

class Dept {
	int size;
	int* scores;
public:
	Dept(int size) {
		//cout << "기본 생성자 실행" << endl;
		this->size = size;
		scores = new int[size];
	}
	/*
	Dept(const Dept& dept){
		//cout << "복사 생성자 실헹" << endl;
		this->size = dept.size;
		this->scores = new int[dept.size];
		for (int i = 0;i < this->size;i++)
			scores[i] = dept.scores[i];
	}
	*/
	~Dept() {
		if (this->scores) {
			//cout << "동적 메모리 반환" << endl;
			delete[]scores;
		}
	}
	int getSize() {
		//cout << this->size << "개 사이즈" << endl;
	return this->size;
	}
	void read() {
		cout << size << "개 정수 입력 >> ";
		for (int i = 0;i < size;i++)
			cin >> scores[i];
	}
	bool isOver60(int index) {
		if (this->scores[index] > 60) {
			//cout << this->scores[index] << ' ' << endl;
			return true;
		}
		else {
			//cout << index<<"  :  "<<this->scores[index] << " under 60" << endl;
			return false;
		}
	}
};
int countPass(Dept &dept) {
	int count = 0;
	for (int i = 0;i < dept.getSize();i++)
		if (dept.isOver60(i)) count++;
	return count;
}

int main() {
	Dept com(10); // size에 10 전달
	com.read(); // 10명 데이터 받아 scores에 저장
	int n = countPass(com);
	cout << "60점 이상은 " << n << "명" << endl;
}
728x90
반응형
Comments