'basic > C++' 카테고리의 다른 글

8. 상속  (0) 2018.05.17
6. 함수중복과 static멤버  (0) 2018.05.15
5. 함수와 참조, 복사생성자  (0) 2018.05.03
4. 객체 포인터와 객체배열, 객체의 동적생성  (0) 2018.04.10
3. 클래스와 객체  (0) 2018.03.22

1. 함수 중복의 조건


  • 중복된 함수들의 이름이 동일 하여야 한다.
  • 중복된 함수들은 매개 변수 타입이나 매개 변수의 개수가 달라야 한다.
  • 함수 중복에 리턴 타입은 고려되지 않는다.


2. 함수중복의 예(예제 6-2 소스, 실행과정을 설명)


#include <iostream>


using namespace std;


int sum(int a){ // 1번 sum 함수 : a에서 b까지 합하기 

int s = 0;

for(int i = 0; i<=a; i++){

s+=i;

}

return s;

}


int sum(int a, int b){ // 2번 sum 함수 : 0에서 a까지 합하기 

int s = 0;

for(int i = a; i<=b; i++){

s+=i;

}

return s;

}


int main(int argc, char** argv) {

cout << sum(3, 5) << endl; //2번 sum 함수 실행이 되어 3부터 5까지 합해진 값을 출력 

cout << sum(3) << endl; //1번 sum 함수 실행이 되어 0부터 3까지 합해진 값을 출력 

cout << sum(100) << endl; //1번 sum 함수 실행이 되어 0부터 100까지 합해진 값을 출력 

return 0;

}




3. 디폴트 매개변수

   (1) 제약조건 : 디폴트 매개 변수는 모두 끝 쪽에 몰려 선언되어야 함

ex) void calc(int a, int b=5, int c, int d=0); X

     void calc(int a=0, int b); X

     void calc(int a, int b, int c=0, int d=0); O

   (2) 예제(프로그램6-5 소스+주석)


#include <iostream>


using namespace std;

/* 1번함수 

void fillLine(){ //25개의 '*'문자를 한 라인에 출력 

for(int i=0; i<25; i++){

cout << '*';

}

cout << endl;

}

2번함수 

void fillLine(int n, char c){ //n개의 c 문자를 한 라인에 출력 

for(int i=0; i<n; i++){

cout << c;

}

cout << endl;

}

*/

void fillLine(int n=25, char c='*'){ //1번과 2번 함수를 디폴트 매개 변수를 이용하여 하나의 함수로 만듬. n개의 c문자를 한 라인에 출력 

for(int i=0; i<n; i++){

cout << c;

}

cout << endl;

}


int main(int argc, char** argv) {


fillLine(); // 디폴트 매개변수에 의해 25개의 *를 한 라인에 출력한다. 

fillLine(10, '%'); // 매개변수에 입력값이 있으므로 10개의 %를 한 라인에 출력한다. 


return 0;

}



4. 함수 중복의 모호성


함수 중복을 허용하는 조건을 갖춘 경우에도 중복된 함수에 대한 호출이 모호해지는 경우가 발생한다. 이러한 경우 컴파일러는 오류를 발생시키므로 모호하지 않게 작성해야 한다.


아래는 함수 중복으로 인한 모호성이 발생하여 컴파일러가 오류를 내는 경우이다.

  • 형 변환으로 인한 모호성
    ex)float square(float a);
       double square(double a);
  • 참조 매개 변수로 인한 모호성
    ex)int add(int a, int b);
        int add(int a, int &b);
  • 디폴트 매개 변수로 인한 모호성
    ex)void msg(int id)
        void msg(int id, string s="")


4. static멤버의 특징


 static 맴버는 프로그램이 시작할 때 생성되고 프로그램이 종료할 때 소멸된다. 변수나 함수가 선언된 범위 내에서 사용하고 전역(global) 혹은 지역(local)로 구분한다.


 쉽게 설명해서 눈과 공기 모두 사람이 소유하는 맴버 라는 공통점을 가지고 있지만, 눈은 각 사람마다 있고 공기는 모든 사람이 공유한다는 차이점이 있다. 공기와 같은 맴버가 static 맴버이고 눈과 같은 맴버가 non-static 맴버이다. non-static 맴버는 객체가 생성 될 시, static은 객체가 생기기전에 이미 생성되어 있고 객체가 사라져도 소멸되지 않는다.


 그렇기 때문에 non-static 맴버는 인스턴스(instance) 맴버라고 부르며 static 맴버는 클래스(class)맴버라고 부른다.


5. static활용 예제(예제6-10소스 + 주석)

'basic > C++' 카테고리의 다른 글

8. 상속  (0) 2018.05.17
7. 프렌드와 연산자 중복 (비어있습니다)  (0) 2018.05.17
5. 함수와 참조, 복사생성자  (0) 2018.05.03
4. 객체 포인터와 객체배열, 객체의 동적생성  (0) 2018.04.10
3. 클래스와 객체  (0) 2018.03.22

1. 값에 의한 호출방법 : 값에 의한 호출은 실인자의 값을 함수 매개 변수에 복사한다. 매개변수와 실인자는 서로 다른 공간을 독립적으로 사용한다. 그렇기 때문에 함수 내에서 실인자를 손상 시키는 일은 없다.


2. 주소에 의한 호출방법 : 주소에 의한 호출은 함수 호출 시 주소가 매개 변수로 전달된다. 매개변수와 실인자는 공간을 공유한다. 실인자의 주소를 넘겨주어 의도적으로 함수 내에서 실인자의 값을 변경하고자 할 때 이용 될 수 있다.


3. 참조에 의한 호출방법 : 참조 변수를 선언하여 사용한다. 참조 변수를 선언할때는 &기호를 사용한다. 참조 변수란 이미 선언된 변수에 대한 별명(alias)이다. 참조 변수가 선언될 시 이름만 생성되며 별도의 공간이 할당되지 않는데 원본 변수의 공간을 공유한다.


참조 변수 선언 시 주의 사항이 있는데, 어떤 변수에 대한 참조인지 초기화를 시켜주어야 한다. 그리고 참조 변수는 공간을 별도로 할당하지 않기 때문에 배열을 만들 수 없다.


4. 값에 의한 호출 예(예제 5-1, 값에 의한 호출의 문제점 정리)


#include <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) { // c라는 독립적인 공간을 사용하기 때문에 

int r = c.getRadius(); // 매개변수에는 다시 선언하며 받아준다. 

c.setRadius(r+1); // 하지만 생성자는 호출하지 않는다. 

} // 눈에 보이지 않지만 복사 생성자란 녀석이 있음 


int main(int argc, char** argv) {

Circle waffle(30);

increase(waffle);

cout << waffle.getRadius() << endl;

system("pause");

return 0;

}



5. 참조에 의한 호출 예제(예제 5-3, 소스, 결과, 주석)


#include <iostream>

using namespace std;


int main(int argc, char** argv) {

cout << "i" << '\t' << "n" << '\t' << "refn" << endl;

int i = 1;

int n = 2;

int &refn = n; //참조변수 refn을 선언. refn은 n의 별칭과 같은 것이다. 

n=4; //refn은 n의 공간을 공유하기 때문에 n이 4가 되면 refn도 4가 된다. 

refn++; //refn이 1이 증가하면 n도 증가, 5 와 5가 된다. 

cout << i << '\t' << n << '\t' << refn << endl; // 1 5 5

refn = i; //refn에 i의 값을 대입시킨다.refn과 n 그리고 i 모두 1이 된다. 

refn++; //refn이 증가하면 n도 같이 증가한다. refn과 n은 2가 된다. 

cout << i << '\t' << n << '\t' << refn << endl; // 1 2 2

int *p = &refn; //p가 refn의 주소를 가진다. 즉 p는 n의 주소를 가진다. 

*p = 20; //p가 가르키는 곳이 20이 된다. 즉 refn과 n 둘다 20이 된다. 

cout << i << '\t' << n << '\t' << refn << endl; // 1 20 20

return 0;

}



6. 참조에 의한 호출의 장점(예제 5-5, 소스, 결과, 주석)


#include <iostream>

using namespace std; 


bool average(int a[], int size, int &avg){ //참조 매개 변수 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 argc, char** argv) {

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;


return 0;

}



+ Recent posts