Jam's story
[C++] 함수의 참조, 복사 생성자 본문
이해가 어려워서 계속 반복중인 파트... 다시 정리하면서 공부하자 !!!!
함수의 참조
값에 의한 호출 ->원본의 값을 훼손하지 않는다.
주소에 의한 호출 -> 원본의 값도 바뀜
주소에 의한 호출
void increse(Circle *p){ //내용 } int main(){ Circle c(30); increase(&c); }
참조변수
원본객체에 연산이 됨 =원본이 변형된다는 말 생성자 , 소멸자 모두 실행되지 않는다
int &refn= n ; -> refn은 n의 별명, refn의 값을 바꾸면 n의 값도 같이 바꿔짐 둘은 동일한 변수
Circle &c=circle
참조변수는 초기화로 지정된 원본 변수의 공간을 공유한다.
참조변수에 대한 포인터도 만들수 있다.
int *p=&refn; *p=20;
참조변수 선언시 주의사항
-초기화가 없다면 컴파일 오류
-참조자 &의 위치는 무관 변수타입이랑 변수명 사이에 오기만 하면됨
-참조변수의 배열을 만들수 없다.-참조변수에 대한 참조선언이 가능하다 int &r=refn;
char c = 'a';
char* p = &c; //p는 c의 주소를 가짐
*p = 'b'; //*p=c
cout << *p<<' '<<c<<endl; //c='b'
char& an = c; //an는 c의 별명
an = 'c';
cout << an<< ' '<<c; //an=c;
얕은복사와 깊은 복사
깊은 복사는 얕은 복사와 달리 메모리도 복사되어있기때문에, 원본가 사본의 변수는 서로 다른 메모리를 가리킨다.
얕은복사는 메모리까지는 복사되지 않았기에 , 원본과 사본이 같은 메모리를 가르킨다. 즉 사본의 값을 변경하면 원본도 변경된다는 뜻이다.
복사생성자 생성class ClassName{ ClassNmae(ConstName& c) };class Circle{ Circle(int r); Circle(const Circle& c); }; int main(){ Circle src(30); Circle dest(src); }복사생성자의 규칙
*복사생성자는 클래스에 오직 한개만 선언할 수 있다.
*자기 클래스에 대한 참조로 선언된다.
*매개변수는 오직하나이다.
깊은 복사생성자 구현
Person:: Person(const Person& p) 처럼 자기 자신클래스의 참조를 만들어준다
p(객체의) . name 혹은 .id 로 접긎ㄴ
char *name 이기 때문에, name에 new char[길이+널문자]; 배열 선언
그 배열에 char을 넣어줘야하니, for문이나 strcpy를 사용
strcpy(a,b) b를 a에 복사시키는것
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(int id, const char* name) { // 생성자
this->id = id;
int len = strlen(name); // name의 문자 개수
this->name = new char[len + 1]; // name 문자열 공간 핟당
strcpy(this->name, name); // name에 문자열 복사
}
실습문제 다시풀기
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
class Circle {
public:
void swap(int &a,int &b);
};
void Circle::swap(int& a, int& b) {
int tmp;
tmp = a;
a = b;
b = a;
}
int main() {
int m = 2;
int n = 9;
swap(m, n);
cout << m << ' ' << n;
}
2번
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
void half(double& su) {
su /= 2;
}
int main() {
double n = 20;
half(n);
cout << n;
}
3번
s3에만 참조를 줘도 된다
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
void combine(string s1, string s2, string& s3) {
s3 = s1 + " " + s2;
}
int main() {
string text1("i love you"), text2("very much");
string text3;
combine(text1, text2, text3);
cout << text3;
}
4번
이거 왜 결과가 숫자가 제대로 안나오는지 모르겠다. .-> 해결
else { big = b; }
return false;
} 이부분에서 return false 를 먼저써서
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
bool bigger(int a, int b, int& big){
if (a == b) { return true; }
else {
if (a > b) { big = a; }
else { big = b; }
return false;
}
}
int main() {
int a, b, big;
a = 5; b = 10;
if (bigger(a, b, big)) {
cout << "두 수는 같습니다" << endl;
}
else {
cout << a << "와 " << b << "중 큰 수는 " << big << "입니다." << endl;
}
return 0;
}
5번
#include <iostream>
#include <string>
using namespace std;
class Circle {
int radius;
public:
Circle(int r) { radius = r; }
int getRadius() { return radius; }
void setRadius(int r) { radius = r; }
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();
return 0;
}
6번
#include <iostream>
#include <string>
using namespace std;
char& find(char a[], char c, bool& success){
for (int i = 0; i < strlen(a); i++) {
if (a[i] == c) {
success = true;
return a[i];
}
else {
success = false;
}
}
}
int main() {
char s[] = "Mike";
bool b = false;
char& loc = find(s, 'M', b);
if (b == false) {
cout << "M을 발견할 수 없다 " << endl;
return 0;
}
loc = 'm';
cout << s << endl;
return 0;
}
7번
이건 다시봐도 문제가 어렵다... pop 팝하여 n개에 저장 .. 이게 뭔소랴.
#include <iostream>
#include <string>
using namespace std;
class MyIntStack {
int p[10];
int tos;
public:
MyIntStack() { tos = -1; }
bool push(int n);
bool pop(int& n);
};
bool MyIntStack::push(int n) {
if (tos >= 9) return false;
p[++tos] = n;
return true;
}
bool MyIntStack::pop(int& n) {
if (tos < 0) return false;
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";
}
cout << endl;
return 0;
}
8번
#include <iostream>
#include <string>
using namespace std;
class MyIntStack {
int* p;
int size;
int tos;
public:
MyIntStack():MyIntStack(1){}
MyIntStack(int size);
MyIntStack(const MyIntStack& s);
~MyIntStack() { delete[] p; }
bool push(int n);
bool pop(int& n);
};
MyIntStack::MyIntStack(int size) {
this->p = new int[size];
this->size = size;
this->tos = -1;
}
MyIntStack::MyIntStack(const MyIntStack& s) {
p = new int[s.size];
this->size = s.size;
this->tos = s.tos;
for (int i = 0; i < s.size; i++) {
this->p[i] = s.p[i];
}
}
bool MyIntStack::push(int n) {
if (tos >= 9) return false;
p[++tos] = n;
return true;
}
bool MyIntStack::pop(int& n) {
if (tos < 0) return false;
n = p[tos--];
return true;
}
int main() {
MyIntStack a(10);
a.push(10);
a.push(20);
MyIntStack b = a;
b.push(30);
int n;
a.pop(n);
cout << "스택 a에서 팝한 값 " << n << endl;
b.pop(n);
cout << "스택 b에서 팝한 값 " << n << endl;
return 0;
}
9번
틀렸었던 이유-> retrun *this.
acc.add(5).add(6) 이부분을 보면 객체 자신 this가 아닌 *this로 해야한다.
#include <iostream>
#include <string>
using namespace std;
class Accumulator {
int value;
public:
Accumulator(int value);
Accumulator& add(int n);
int get();
};
Accumulator::Accumulator(int value) {
this->value = value;
}
Accumulator& Accumulator:: add(int n){
this->value += n;
return *this;
}
int Accumulator::get() {
return value;
}
int main() {
Accumulator acc(10);
acc.add(5).add(6).add(7);
cout << acc.get();
return 0;
}
10번
틀린이유->
1. Buffer& append 함수는 Buffer 클래스 밖에 선언해야한다
2. 매개변수에서 (Buffer b 와 Buffer& b는 결과가 다르다
Buffer b라고 하면, 원본의 값이 바뀌지 않기때문에 main함수에서 호출했을시에 값이 원본으로 출력한다
Buffer& b라고 하면 원본값이 바뀌기 때문에 string이 추가된 것이 반환된다
#include <iostream>
#include <string>
using namespace std;
class Buffer {
string text;
public:
Buffer(string text) { this->text = text; }
void add(string next) { text += next; }
void print() { cout << text << endl; }
};
Buffer& append(Buffer& b, string s) {
b.add(s);
return b;
}
int main() {
Buffer buf("Hello");
Buffer& temp = append(buf, "Guys");
temp.print();
buf.print();
return 0;
}
11번
string을 쓰면 메모리 할당받을 필요가 없다. (char *title 과 비교)
#include <iostream>
#include <string>
using namespace std;
class Book {
string title;
int price;
public:
Book(string title, int price);
Book(Book& b);
~Book() { }
void set(string title, int price);
void show() { cout << title << ' ' << price << "원" << endl; }
};
Book::Book(string title, int price) {
this->title = title;
this->price = price;
}
void Book::set(string title, int price) {
this->title = title;
this->price = price;
}
Book::Book(Book& b) {
this->title = b.title;
this->price = b.price;
}
int main() {
Book cpp("명품C++", 10000);
Book java = cpp;
java.set("명품자바", 12000);
cpp.show();
java.show();
return 0;
}
12번 안틀리고 성공!!
#include <iostream>
#include <cstring>
using namespace std;
class Dept {
int size;
int* scores;
public:
Dept(int size) { this->size = size; scores = new int[size]; }
Dept(const Dept& dept);
~Dept(){}
int getSize() { return size; }
void read();
bool isOver60(int index);
};
Dept::Dept(const Dept& dept) {
this->size = dept.size;
scores = new int[dept.size];
}
void Dept::read() {
cout << size << "개의 점수 입력";
for (int i = 0; i < size; i++) {
cin >> scores[i];
}
}
int countPass(Dept& dept) {
int count = 0;
for (int i = 0; i < dept.getSize(); i++) {
if (dept.isOver60(i)) count++;
}
return count;
}
bool Dept:: isOver60(int index) {
if (scores[index] > 60)return true;
else return false;
}
int main() {
Dept com(10);
com.read();
int n = countPass(com);
cout << "60점 이상은" << n;
}
'2021-2학기 > C++' 카테고리의 다른 글
c++기본 (0) | 2021.10.26 |
---|---|
c4996 에러 해결방법 (0) | 2021.10.24 |
2장 틀렸던 문제 다시풀어보기 (0) | 2021.10.24 |
[명품 c++ programming] 5장 open challenge (0) | 2021.10.10 |
[C++ programming ] 실습문제 6장 (0) | 2021.10.08 |