STUDY BLOG

명품 C++ programming Chapter 05 예제 본문

Software/C++

명품 C++ programming Chapter 05 예제

쥬루 2020. 11. 20. 01:05

명품 C++ Programming Chapter 05 예제

 

예제 5-1 '값에 의한 호출' 시 매개 변수의 생성자 실행되지 않음

#uinclude <iostream>
using namespace std;

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

Circle::Circle() {
	radius = 1;
    cout << "생성자 실행 radius = " << radius << endl;
}

Circle::Circle(int radius) {
	this->radius = radius;
    cout << "생성자 실행 radius = " << radius << endl;
}

Circle::~Circle() {
	cout << "소멸자 실행 radius = " << radius << endl;
}

void increase(Circle c) {
	int r = c.getRadius();
    c.setRadius(r+1);
}

int main() {
	Circle waffle(30);
    increase(waffle);
    cout << waffle.getRadius() << endl;
}

 

 

예제 5-2 객체 리턴

#include <iostream>
using namespace std;

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

Circle getCircle() {
	Circle tmp(30);
    return tmp;
}

int main() {
	Circle c;
    cout << c.getArea() << endl;
    
    c=getCircle();
    cout << c.getArea() << endl;
}

 

예제 5-3 기본 타입 변수에 대한 참조

#include <iostream>
using namespace std;

int main() {
	cout << "i" << '\t' << "n" << '\t' << "refn" << endl;
    int i=1;
    int n=2;
    int &refn = n;
    n=4;
    refn++;
    cout << i << '\t' << n << '\t' << refn << endl;
    
    refn = i;
    refn++;
    cout << i << '\t' << n << '\t' << refn << endl;
    
    int *p = &refn;
    *p = 20;
    cout << i << '\t' << n << '\t' << refn << endl;
    
}

 

예제 5-4 객체에 대한 참조

#include <iostream>
using namespace std;

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

int main() {
	Circle circle;
    Circle &refc = circle;
    refc.setRadius(10);
    cout << refc.getArea() << " " << circle.getArea();
}

 

예제 5-5 참조 매개 변수로 평균 리턴하기

#include <iostream>
using namespace std;

bool average(int a[], int size, int& avg){
	if(size <=0)
    	return false;
    int sum=0;
    
    for(int i=0;i<size;i++)
    	sum+=a[i];
    
    avg = sum/size;
    return true;
}

int main() {
	int x[] = {0,1,2,3,4,5};
    int avg;
    
    if(average(x,6,avg)) cout << "평균은 " << avg << endl;
    else cout << "매개 변수 오류" << endl;
    
    if(average(x,-2,avg)) cout << "평균은 " << avg << endl;
    else cout << "매개 변수 오류" << endl;
    
}

 

예제 5-6 참조에 의한 호출로 Circle 객체의 참조 전달

#uinclude <iostream>
using namespace std;

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

Circle::Circle() {
	radius = 1;
    cout << "생성자 실행 radius = " << radius << endl;
}

Circle::Circle(int radius) {
	this->radius = radius;
    cout << "생성자 실행 radius = " << radius << endl;
}

Circle::~Circle() {
	cout << "소멸자 실행 radius = " << radius << endl;
}

void increase(Circle &c) {
	int r = c.getRadius();
    c.setRadius(r+1);
}

int main() {
	Circle waffle(30);
    increase(waffle);
    cout << waffle.getRadius() << endl;
}

 

예제 5-7 참조 매개 변수를 가진 함수 만들기 연습

#include <iostream>
using namespace std;

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

int main() {
	Circle donut;
    readRadius(donut);
    cout << "donut의  " << donut.getArea() << endl;
}

 

예제 5-8 참조 리턴

#include <iostream>
using namespace std;

char& find(char s[], int index) {
	return s[index];
}

int main() {
	char name[] = "Mike";
    cout << name << endl;
    
    find(name, 0) = 'S';
    cout << name << endl;
    
    char& ref = find(name, 2);
    ref = 't';
    cout << name << endl;
}

 

예제 5-9 Circle 클래스의 복사 생성자와 객체 복사

#uinclude <iostream>
using namespace std;

class Circle {
private:
	int radius;
public:
	Circle(const Circle& c);
    Circle() { radius = 1 };
    Circle(int radius) { this->radius=radius; }
    double getArea() { return 3.14*radius*radius; }
};

Circle::Circle(const Circle& c) {
	radius = 1;
    cout << "생성자 실행 radius = " << radius << endl;
}

Circle::Circle(int radius) {
	this->radius = c.radius;
    cout << "복사 생성자 실행 radius = " << radius << endl;
}

int main() {
	Circle src(30);
    Circle dest(src);
    
    cout << "원본의 면적 = " << src.getArea() << endl;
    cout << "사본의 면적 = " << dest.getArea() << endl;
}

 

예제 5-10 얕은 복사 생성자를 사용하여 프로그램이 비정상 종료되는 경우

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

class Person {
	char* name;
    int id;
public:
	Person(int id, const char* name);
    ~Person();
    void changeName(const char *name);
    void show() { cout << id << ', ' << name << endl; }
};

Person::Person(int id, const char* name) {
	this -> id = id;
    int len = strlen(name);
    this -> name = new char [len+1];
    strcpy(this->name, name);
}

Person::~Person() {
	if(name)
    	delete [] name;
}

voi Person::changeName(const char* name) {
	if(strlen(name) > strlen(this->name))
    	return;
    strcpy(this->name, name);
}

int main() {
	Person father(1, "Kitae");
    Person dauther(father);
    
    cout << "dauther 객체 생성 직후 ----" << endl;
    
    father.show();
    dauther.show();
    
    dauther.changeName("Grace");
    cout << "daughter 이름을 Grace 로 변경한 후 ----" << endl;
    father.show();
    daughter.show();
    
    return 0;
    
}

 

예제 5-11 깊은 복사 생성자를 가진 정상적인 Person 클래스

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

class Person {
	char* name;
    int id;
public:
	Person(int id, const char* name);
    Person(const Person& person);
    ~Person();
    void changeName(const char *name);
    void show() { cout << id << ', ' << name << endl; }
};

Person::Person(int id, const char* name) {
	this -> id = id;
    int len = strlen(name);
    this -> name = new char [len+1];
    strcpy(this->name, name);
}

Person::Person(const Person& person) {
	this -> id = person.id;
    int len = strlen(person.name);
    this -> name = new char [len+1];
    strcpy(this->name, person.name);
	cout << "복사 생성자 실행. 원본 객체의 이름" << this->name << endl;
}

Person::~Person() {
	if(name)
    	delete [] name;
}

voi Person::changeName(const char* name) {
	if(strlen(name) > strlen(this->name))
    	return;
    strcpy(this->name, name);
}

int main() {
	Person father(1, "Kitae");
    Person dauther(father);
    
    cout << "dauther 객체 생성 직후 ----" << endl;
    
    father.show();
    dauther.show();
    
    dauther.changeName("Grace");
    cout << "daughter 이름을 Grace 로 변경한 후 ----" << endl;
    father.show();
    daughter.show();
    
    return 0;
    
}

 

예제 5-12 묵시적 복사 생성에 의해 복사 생성자가 자동 호출되는 경우

coid f(Person person) {
	person.changeName("dummy");
}

Person g() {
	Person mother(2, "Jane");
    return mother;
}

int main() {
	Person father(1, "Kitae");
    Person son = father;
    f(father);
    g();
}