1. 상속의 장점 : 상속은 동일한 코드를 여러번 중복 할 필요 없이 상속관계로 선언하면 물려 받기만 하면 되는 간결함이라는 장점이 있다. 또한 클래스 관계를 계층 관계로 표현 함으로써 프로그램의 구조적인 관계 파악을 쉽게 해준다. 가장 큰 장점은 역시 재사용성이 좋고 소프트웨어의 생산성을 향상 시켜준다는 장점이 있다.  


2. 상속의 예 (예제 8-1 소스코드, 주석)


#include <iostream>

#include <cstdlib> 


using namespace std;


class Point{

int x, y; //x, y의 좌표값

public :

void set(int x, int y){

this->x=x;

this->y=y;

}

void showPoint(){

cout << "(" << x << ", " << y << ")" << endl;

}

};


class colorPoint : public Point{

string color;

public:

void setColor(string color){

this->color=color;

}

void showColorPoint(){

cout << color << ": ";

showPoint(); //기본 클래스의 맴버 함수를 호출한다. 

}

};


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

Point p; //기본 클래스의 객체 p를 생성한다.

colorPoint cp; //파생 클래스의 객체 cp를 생성한다.

//재사용성 확인하기

cp.set(3,4);

cp.setColor("Red");

cp.showColorPoint(); 

return 0;

}



3. 상속관계에서 생성자의 실행 예(예제코드, 주석, 실행결과)


#include <iostream>


using namespace std; 


class A{

int x;

public:

A(){

x = 0;

}

A(int x){

this->x = x;

cout << "A 맴버 변수 x = " << x << endl;

}

};


class B : public A{

int y;

public:

B(int x, int y) : A(x+5){

this->y =y;

cout << "B 맴버 변수 x = " << x << " B 맴버 변수 y = "<< y << endl;

}

};


class C : public B{

int m;


public:

C(int x, int y, int z) : B(x, y){

m = x*y*z;

cout << "C 맴버 변수 x = " << x << " C 맴버 변수 y = "<< y << " C 맴버 변수 m = "<< m << endl;

}

};


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

C c(3,5,2); //c 객체의 생성자 호출순서는 C > B > A 로 거슬러 올라가서 생성자의 실행 순서는 A > B > C 순으로 된다. 이 과정에서 A의 매개변수가 있는 생성자가 호출 될 때 A의 맴버 변수 x 의 값이 8이 되고 그 다음 실행 되는 B의 생성자에서 B의 맴버 변수가 x는 3 y는 5가 되고 마지막으로 C의 생성자가 실행되어 C의 맴버 변수 x는 3 y는 5 m 은 30이 됩니다. 

한눈에 알아보기 쉬운 실행결과 참조

cout << endl;

B b(3,4);

return 0;

}



4. 동적바인딩의 조건(예제코드, 주석, 실행결과)

1) 파생 클래스의 함수를 오버라이딩 한다.(virtual 키워드를 사용) 

2) 업캐스팅을 시켜준다.

(1과 2번의 조건은 프로그램에서 코딩해야하는 것)


#include <iostream>


using namespace std; 


class Shape{ //base class 기본 클래스

//오버라이딩 시키기 위하여 virtual 키워드를 붙인다. (가상 함수 임을 나타냄) 

public:

virtual void draw()= 0; //순수가상함수란 선언만하는 가상함수이다. 상속받는 파생클래스는 반드시 구현해서 사용 해야만 한다. 

//c++ 에서는 순수가상함수를 가지는 클래스를 추상클래스라고 한다. 

/*{

cout << " 도형을 그린다. " << endl;

}*/

}; 


class Circle:public Shape{ //derive class 파생 클래스 

//오버라이딩 : 기본 클래스의 맴버 함수를 파생 클래스에서 재정의 한다. 

public:

virtual void draw(){

cout << " 원을 그린다. " << endl;

}

};

//동적바인딩의 조건 

//1.파생 클래스의 함수를 오버라이딩 한다.(virtual 키워드를 사용) 

//2.업캐스팅을 시켜준다. (1과 2번의 조건은 프로그램에서 코딩해야하는 것) 

class Rect:public Shape{

public:

virtual void draw(){

cout << " 사각형을 그린다. " << endl;

}

};


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

//실습 1 : 맴버 함수 호출 

//heap영역에 할당되고 결과로 주소 즉 포인터가 넘어오기 때문에 받을때 포인터 변수로 받는다. 

//Shape *p = new Shape(); //new 동적할당 

//p->draw(); //실행결과 : 도형을 그린다. (기본 클래스의 내용이 출력된다.) 

//실습 2 : 오버라이딩 된 결과 확인

Shape *q = new Circle();

q->draw(); //실행결과 : 원을 그린다. 

Shape *r = new Rect();

r->draw(); //실행결과 : 사각형을 그린다. 

//업캐스팅이란 파생 클래스에서 생성된 포인터를 기본 클래스의 포인터로 보내준다. 

return 0;

}



'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;

}



. 객체포인터 


  (1) 객체 포인터 변수선언방법

아주 간단하다 만들고자 하는 타입과 만들고자 하는 변수의 이름앞에 *(aesterik)을 붙여서 만들어준다.

ex) Circle *p;

Circle 타입의 객체에 대한 포인터 변수 p를 만들어준다.

  (2) 포인터변수에 주소지정방법

포인터 변수에 객체의 주소를 지정하기 위해 & 연산자를 사용한다. 객체 이름 앞에 & 연산자를 사용하면 해당 객체의 주소가 반환된다.

ex) p = &abc;

abc라는 객체의 주소를 포인터 변수 p에 지정시킨다.

  (3) 포인터를 이용한 객체 멤버접근

일반적으로 객체들의 맴버에 접근 할때는 . 연산자를 사용한다. 덫붙여 객체 포인터로 맴버에 접근을 할때에는 -> 연산자 화살표 같이 생긴 이 연산자를 사용한다.

ex)

d = donut.getArea(); 객체가 맴버에 접근할 때 . 연산자를 사용한다

d = p->getArea(); 객체 포인터로 맴버에 접근할때 -> 연산자를 사용한다.

d = (*p).getArea(); 위의 코드와 같은 결과.


총 예제 및 소스코드


#include <cstdlib>

#include <iostream>


using namespace std;


class Circle {

int radius;

public:

Circle() { 

radius = 1; 

}

Circle(int r) { 

radius = r; 

}  

double getArea();

}; 


double Circle::getArea() {

return 3.14*radius*radius;

}


int main(int argc, char *argv[])

{

    Circle donut; //기본생성자 호출 반지름이 1 

Circle pizza(30); //매개변수 1개 생성자 호출 반지름이 매개변수로 들어오는 값  

cout << donut.getArea() << endl;

Circle *p; //포인터 변수 p 선언 

p = &donut; //포인터 변수에 기본생성자로 만들어진 donut 객체의 주소를 지정 

cout << p->getArea() << endl; //p가 가리키고 있는 donut 객체의 면적 출력 

cout << (*p).getArea() << endl;

p = &pizza; //포인터 변수에 매개변수 1개 포함한 생성자로 만들어진 pizza 객체의 주소를 지정 

cout << p->getArea() << endl; //p가 가리키고 있는 pizza 객체의 면적 출력 

cout << (*p).getArea() << endl;

    

    system("PAUSE");

    return EXIT_SUCCESS;

}


2, 객체배열


  (1) 객체 배열 선언방법

객체 배열은 원소가 객체라는 점을 제외하고 일반 배열과 크게 다르지 않다. 객체 배열을 선언하는 방법은 만들고자 하는 객체 타입과 배열의 이름, 크기를 지정해주면 된다. 이때 객체 배열 선언문은 반드시 기본 생성자를 호출한다.

  (2) 객체 배열을 이용한 멤버접근

객체 배열을 사용하여 맴버에 접근하는 방법은 원소 객체와 맴버 사이에 . 연산자를 사용하면 된다.

  (3) 객체배열 소멸순서

#include <cstdlib>

#include <iostream>


using namespace std;


class Circle {

int radius;

public:

Circle() { 

radius = 1; 

}

Circle(int r) { 

radius = r; 

}  

void setRadius(int r) {

radius = r;

}

double getArea();

}; 


double Circle::getArea() {

return 3.14*radius*radius;

}


int main(int argc, char *argv[])

{

    Circle circleArray[3] = { Circle(10), Circle(20), Circle() }; //매개 변수가 있는 생성자로 객체 2개가 생성되고 그다음 기본 생성자에 의해 생성된다. 

    

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

    cout << "Circle " << i << "의 면적은 " << circleArray[i].getArea() << endl;

}

    //main 함수가 종료 되고 나면 객체 배열이 소멸되며 높은 인덱스에서부터 원소 객체가 순차적으로 소멸된다. 

    system("PAUSE");

    return EXIT_SUCCESS;

}


3. 객체배열 예제정리 (프로그램 4-9) 주석


(1)동적생성 (주석 1번)

(2)객체배열을 동적생성 -> 초기화 (주석 2번)

(3)동적할당받은 메모리반납 (주석 3번)



#include <iostream>

#include <cstdlib>


using namespace std;


class Circle{

int radius;

public:

Circle(); //기본 생성자 

Circle(int r); //매개변수 포함 생성자 

~Circle(); //소멸자 

void setRadius(int r){

radius = r;

}

double getArea(){

return 3.14 * radius * radius;

}

};


Circle::Circle(){

radius = 1;

cout << " 생성자 실행 radius = " << radius << endl;


Circle::Circle(int r){

radius = r;

cout << " 생성자 실행 radius = " << radius << endl;

}


Circle::~Circle(){

cout << " 소멸자 실행 radius = " << radius << endl;

}



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

//객체 배열 생성 - 동적할당 (new) -> 힙(heap) 영역에 생성

Circle *pArray = new Circle[3]; //객체 배열을 동적 생성 한다. 동적할당을 받으면 배열의 주소가 포인터로 넘어 온다 그렇기 때문에 객체 포인터로 주소를 받는다.*1 //객체 배열을 동적으로 생성한다. 객체 배열을 생성할때에는 초기화 시키기 위해 자동으로 기본생성자 함수가 호출이 된다.*2

//반지름을 설정

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

pArray[i].setRadius(10);

}

//객체 배열의 면적을 출력

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

cout << pArray[i].getArea() << endl;

}

 

Circle *p = pArray; //*p는 pArray의 주소를 대입

 

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

cout << p->getArea() << endl;

p++; //다음 주소로 증가  

}

 

delete[]  pArray; //힙 영역에 할당받은 객체 배열 공간을 반납하는 구문 

//객체를 동적으로 생성 하고 반환 할때는 delete만 사용하면 되지만

//객체 배열을 반환할때는 delete 뒤에 반드시 [] 를 붙여줘야 한다. *3

return 0;

}


4. string 배열 예제 정리


(1) 객체 생성 비교


#include <iostream>

#include <cstdlib>

#include <string>


using namespace std;


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

//1. 객체생성 (정적 할당) 

string str = "I love";

str.append(" C++"); //접근시 . 연산자를 사용하여 접근한다

cout << str << endl; //append 함수는 문자열울 추가하는 함수이다. 

cout << "\n"; //실행결과 : I love c++ 

 

//2. 객체생성 (동적 할당) - heap 영역에 할당되어진다. 포인터를 받는다. 

string *p = new string("C++"); //선언부의 *은 주소를 저장 

cout << "*p = " << *p << endl; //실행부의 *은 주소의 내용을 출력 

//실행결과 : p* = c++ 

p->append(" Great!! "); //접근시 -> 연산자로 접근

cout << "*p = " << *p << endl; //실행결과 : p* = c++ Great!!

return 0;

}


(2) 예제 4-12 string 배열 선언과 문자열 키 입력 응용 예제 소스


#include <iostream>

#include <cstdlib>

#include <string>


using namespace std;


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

string names[5];

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

cout << " 이름 >> ";

getline(cin, names[i], '\n');

}

string latter = names[0];

for(int i=1 ; i<5 ; i++){

if(latter < names[i]){

latter = names[i];

}

}

cout << " 사전에서 가장 뒤에 나오는 문자열은 " << latter << endl;

return 0;

}




(3) 문자열 다루기


#include <iostream>

#include <cstdlib>

#include <string>


using namespace std;


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


// 1. 문자열 치환 =연산자 

string a = "Java", b= "C++";

cout << " a = " << a << " b = " << b << endl; //실행결과 a = Java b = c++ 

a=b;

cout << " 치환 후 a = " << a << ", b = " << b << endl; //치환 후 실행결과 a=c++, b=c++

// 2. 문자열 비교 compare()

string name = "Hong";

string subName = "GilDong";

int res = name.compare(subName);

if(res==0){

cout << "두 문자열이 같다." << endl;

}

else if(res < 0){ //name 이 alphabet순서에서 앞에 나올경우 

cout << name << " < " << subName << endl;

}

else{ //name 이 alphabet순서에서 뒤에 나올경우 

cout << name << " > " << subName << endl;

}


// 3. 문자열 삽입 insert()

cout << "012345678901234567890\n";

a = "I love C++";

a.insert(2, "really "); // 실행결과 012345678901234567890

// I really love C++ 

// 4. 문자열길이 Length()

int len = a.length();

cout << "문자열의 길이 = " << len << endl; //실행결과 문자열의 길이 = 17

// 5. 문자열삭제 erase()

a.erase(0, 7); //0번 인덱스 부터 7개를 지운다. 6번 인덱스까지 지운다. 

cout << "문자열 0~7까지 삭제" << a << endl; //실행결과 문자열 0~7까지 삭제y love C++

// 6. 문자열일부분 추출 substr()

cout <<    "012345678901234567890\n";

b = "I love C++";

string c = b.substr(2,4); //2번 인덱스부터 4개를 추출한다. 

cout << "c = " << c << endl;

// 7. 문자열 검색 find() 

cout <<    "012345678901234567890\n";

b = "I love love C++";

int index = b.find("love");

cout << "love의 인덱스는 " << index << endl; //실행결과 2 why? 동일한 단어는 처음 나온 단어의 인덱스만 찾는다. 

index = b.find("love", index+1); 

cout << "love의 인덱스는 " << index << endl;

// 8. 인덱스번호를 지정해서 문자를 읽는 방법 at() 

char ch1 = b.at(12);

cout << "12번 인덱스의 문자는 " << ch1 << endl;

return 0;

}


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

6. 함수중복과 static멤버  (0) 2018.05.15
5. 함수와 참조, 복사생성자  (0) 2018.05.03
3. 클래스와 객체  (0) 2018.03.22
2. C++ 프로그래밍의 기본  (0) 2018.03.13
1. C++ 시작  (0) 2018.03.08

1. 클래스의 개념 

클래스(class)란 객체(object)를 정의하는 틀 혹은 설계도이다. 클래스 내에는 이 클래스 내부에 사용 할 수 있는 맴버 변수와 맴버 함수를 선언한다.


클래스를 만들때는 선언부와 구현부를 만들어준다.

클래스의 선언부의 마지막에는 반드시 세미콜론(;)을 붙여준다.

2. 객체의 개념

객체(object)란 클래스라는 틀에서 찍어내어, 맴버 변수 메모리와 햄버 함수 코드를 실제 가지고 프로그램이 실행되는 동안 실존하는 실체 혹은 인스턴스(instance)이다.


객체를 생성하는 방법 중 한가지 : 클래스이름 + 객체이름

ex) Circle 클래스 donut객체를 만드는 방법은 Circle donut; 처럼 만들면 된다.


3. 캡슐화의 개념

캡슐화(encapsulation)란 객체의 구성 요소들을 캡슐로 싸서 보호하고 볼 수 없게 하는 것으로, 객체의 가장 본질적인 특징중 하나이다.

한마디로 객체는 캡슐화를 통해 외부의 접근을 통제하여 자신의 내부 요소들을 보호한다.


4. 클래스작성 예(예제3-1, 소스코드, 주석)


예제 3-1 코드


#include <iostream>

#include <cstdlib>

#include <cstring> 


using namespace std;


//클래스 정의하는 위치는 maim() 함수 위에 적는다. (클래스는 설계도 이기 때문이다.) 

class Circle{ //클래스의 선언부 

public:

int radius; //맴버변수 

double getArea(); //맴버함수 

};


//클래스의 구현부 

double Circle::getArea(){ // 맴버함수 구현시 반드시 :: 범위지정연산자를 붙여준다. 

return 3.14*radius*radius; // 범위지정연산자는 해당 함수가 어디에 속하는지를 알 수 있게 해준다. 


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

//객체생성방법1 (클래스이름 + 객체이름) 

Circle donut;

//생성된 객체로 맴버에 접근하는 방법은 객체이름에 . 연산자를 사용하여 맴버변수를 쓴다. 

donut.radius = 1; // 맴버함수에 접근하는 방법 (객체이름 + . + 맴버변수)

double area = donut.getArea(); //면적을 계산하는 맴버함수를 이용하여 계산한 면적을 area 변수에 저장한다. 

cout << "donut 면적은 " << area << endl;

Circle pizza;

pizza.radius = 30;

area = pizza.getArea();

cout << "pizza 면적은 " << area << endl;

return 0;

}


예제 3-1 내코드


#include <iostream>

#include <cstdlib>

#include <cstring> 


using namespace std;


//클래스 정의하는 위치는 maim() 함수 위에 적는다. (클래스는 설계도 이기 때문이다.) 

class Circle{ //클래스의 선언부 

public:

int radius; //맴버변수 

double getArea(); //맴버함수 

};


//클래스의 구현부 

double Circle::getArea(){ // 맴버함수 구현시 반드시 :: 범위지정연산자를 붙여준다. 

return 3.14*radius*radius; // 범위지정연산자는 해당 함수가 어디에 속하는지를 알 수 있게 해준다. 


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

//객체생성방법1 (클래스이름 + 객체이름) 

Circle donut;

Circle pizza;

//생성된 객체로 맴버에 접근하는 방법은 객체이름에 . 연산자를 사용하여 맴버변수를 쓴다. 

donut.radius = 1; // 맴버함수에 접근하는 방법 (객체이름 + . + 맴버변수)

double area = donut.getArea(); //면적을 계산하는 맴버함수를 이용하여 계산한 면적을 area 변수에 저장한다. 

cout << "도넛의 면적은 " << area << endl;

pizza.radius = 10;

double area2 = pizza.getArea();

cout << "피자의 면적은 " << area2 << endl;

return 0;

}


////////////////////////////////////////////////////////////////////////////////////////////////////////////


#include <iostream>

#include <cstdlib>

#include <cstring> 


using namespace std;


//클래스 정의하는 위치는 maim() 함수 위에 적는다. (클래스는 설계도 이기 때문이다.) 

class Circle{ //클래스의 선언부 


public:

int radius; //맴버변수 

double getArea(); //맴버함수

Circle(); //기본생성자함수 

Circle(int r);

};


//클래스의 구현부 

Circle::Circle(){

radius = 1;

cout << "기본생성자함수 실행" << endl;

cout << "반지름 " << radius << endl; 


Circle::Circle(int r){

radius = r;

cout << "매개변수 1개 있는 생성자함수 실행" << endl;

cout << "반지름 " << radius << endl;

}


double Circle::getArea(){ // 맴버함수 구현시 반드시 :: 범위지정연산자를 붙여준다. 

return 3.14*radius*radius; // 범위지정연산자는 해당 함수가 어디에 속하는지를 알 수 있게 해준다. 


class Rectangle{


public:

int width,height;

double getArea();

};


double Rectangle::getArea(){

return width*height;

}


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

/*

//객체생성방법1 (클래스이름 + 객체이름) 

Circle donut;

//생성된 객체로 맴버에 접근하는 방법은 객체이름에 . 연산자를 사용하여 맴버변수를 쓴다. 

donut.radius = 1; // 맴버함수에 접근하는 방법 (객체이름 + . + 맴버변수)

double area = donut.getArea(); //면적을 계산하는 맴버함수를 이용하여 계산한 면적을 area 변수에 저장한다. 

cout << "donut 면적은 " << area << endl;

Circle pizza;

pizza.radius = 30;

area = pizza.getArea();

cout << "pizza 면적은 " << area << endl;

*/

/*

Rectangle rect;

rect.width=3;

rect.height=5;

cout << "사각형의 면적은 " << rect.getArea() << endl; 

*/

//생성자함수는 객체가 생성될때 자동으로 호출되는 함수이다.

//생성자함수의 이름은 클래스이름과 같은 이름을 쓴다. 

Circle donut; //donut 객체 생성은 매개변수가 없는 객체를 생성하였다는 것이고 

//매개변수가 없는 객체를 생성할때에는 기본 생성자 함수를 호출한다. 

Circle pizza(30); //매개변수가 하나 있는 객체를 생성한다.

 

return 0;

}


5. 생성자함수


   (1) 생성자 함수란?

생성자 함수란 객체를 초기화 시켜주는 함수이다.


   (2) 생성자 함수의 특징

 생성자 함수의 목적인 객체의 생성시 초기화 작업을 해준다. 객체가 만들어질때 이미 그 객체 내에 garbage 값이 들어가 있는데 이를 초기화 시켜준다.

 생성자 함수는 오직 한 번만 실행이 된다. 그 시점은 객체가 생성되는 시점이다.

 생성자 함수는 클래스 이름과 동일하게 작성이 되어진다.

 생성자 함수를 정의 할 때 함수의 원형에 리턴 타입을 선언하지 않는다. 리턴 타입이 없어서 void 타입을 설정해서도 안된다.

 생성자는 중복이 가능하며 오버로딩이 가능하다. 단 매개 변수의 개수나 타입이 서로 다르게 선언되어야 허용 된다.


   (3) 기본생성자가 자동으로 생성되는 경우의 예

 자동으로 만들어질 때는 생성자가 하나도 없는 클래스의 객체를 만들시 보이지 않는 기본 생성자에 의해서 만들어진다.


   (4) 기본생성자가 자동으로 생성되지 않는 경우의 예

 생성자가 하나라도 선언된 클래스의 경우 기본 생성자를 자동으로 삽입하지 않는다.


6. 소멸자함수


  (1) 실행되는 시점

 생성된 객체가 다 활용되고 메모리를 반환하게 되는데 객체가 생성이 되면 다 쓰이고 소멸이 된다.  정확히는 객체가 소멸되는 시점에서 자동으로 호출된다.


  (2) 소멸자함수의 특징(5가지)

  • 소멸자는 객체가 사라질 때 필요한 마무리 작업을 해준다. (객체가 사라지기 전에 필요한 조치를 해준다. 동적으로 할당받은 메모리를 돌려주거나 열어 놓은 파일등을 닫는 것과 같은 일들)
  • 소멸자를 쓸 때엔 소멸자 클래스의 이름 앞에 ~를 붙인다.
  • 소멸자는 리턴 타입이 없고 어떤 값도 리턴해서는 안된다.
  • 생성자완 달리 소멸자는 오직 한 개만 존재한다.(매개 변수도 가지지 않는다.)
  • 소멸자가 선언되어 있지 않으면 기본 소멸자가 자동으로 생성된다.

  (3) 소멸자함수의 실행 예:역순으로 실행되는 과정을 확인


소멸자 함수는 객체가 만들어진 순서의 역순으로 실행된다.


#include <cstdlib>

#include <iostream>


using namespace std;


class Circle {

public:

int radius;

Circle(); // 기본 생성자

Circle(int r); // 매개 변수 있는 생성자

~Circle(); //소멸자 함수 

double getArea();

}; 


Circle::~Circle(){ //소멸자 함수 구현 

cout << "반지름 " << radius << "원 소멸 " << endl;

system("PAUSE");

}


Circle::Circle() {

radius = 1;

cout << "반지름 " << radius << " 원 생성" << endl;

}


Circle::Circle(int r) {

radius = r;

cout << "반지름 " << radius << " 원 생성" << endl;

}


double Circle::getArea() {

return 3.14*radius*radius;

}


int main(int argc, char *argv[])

{

    Circle donut; // 매개 변수 없는 생성자 호출

double area = donut.getArea();

cout << "donut 면적은 " << area << endl;


Circle pizza(30); // 매개 변수 있는 생성자 호출

area = pizza.getArea();

cout << "pizza 면적은 " << area << endl;

    

    system("PAUSE");

    return EXIT_SUCCESS;

}



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

6. 함수중복과 static멤버  (0) 2018.05.15
5. 함수와 참조, 복사생성자  (0) 2018.05.03
4. 객체 포인터와 객체배열, 객체의 동적생성  (0) 2018.04.10
2. C++ 프로그래밍의 기본  (0) 2018.03.13
1. C++ 시작  (0) 2018.03.08


1. 키 입력 받기(원의 면적을 계산하는 예제소스코드), 실행결과, 주석: cin >>  설명


#include <cstdlib> 

#include <iostream>


using namespace std;


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

int width,height;

int radius;

cout << "너비를 입력하세요 : ";

cin >> width;


  //키보드에서 너비를 입력받아 width 변수에 저장해줌 

//cin : 표준 입력 스트림, 값을 입력받는 객체이며 >> 연산자와 함께 이용하여 유저로 부터 키를 입력받는다. 

// >> (스트링 추출연산자) : Enter 키를 칠 때 변수에 키 값을 전달한다. 

cout << "높이를 입력하세요 : ";

cin >> height;

//c++은 실행문 사이에 변수선언이 가능하다.

int area = width * height; 

cout << "면적은 " << area << endl; //endl은 \n과 같은 의미 

cout << "반지름을 입력하세요 : ";

cin >> radius;

double area2 = radius * radius * 3.14;

cout << "원의 면적은 " << area2 << endl;

system("PAUSE");

return 0;

}



2. c++의 문자열


   (1) c-스트링 (사용방법, 예제)


#include <cstdlib> 

#include <iostream>

#include <cstring>


using namespace std;


/* run this program using the console pauser or add your own getch, system("pause") or input loop */


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

//문자열처리1 : c-String 방식 : c-String은 널(Null) 문자로 끝나는 char 배열을 선언해서 사용한다. 

//널 문자에는 '\0' 혹은 0 이 있다. 

char password1[100];

char password2[100];

cout << " 새 암호를 입력하세요 >> ";

cin >> password1;

cout << " 변경한 암호를 확인하세요 (재입력) >> ";

cin >> password2;

if(strcmp(password1,password2) == 0)

{

cout << " 비밀번호 변경완료 ";

}

else

cout << " 비밀번호가 다릅니다. 재설정 하세요 ";

cout << endl; 


return 0;

}


#include <cstdlib> 

#include <iostream>

#include <cstring>


using namespace std;


/* run this program using the console pauser or add your own getch, system("pause") or input loop */


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

//주소입력

char address[100];

cout << " 주소를 입력하시오 : ";

//cin >> address; //cin 함수는 공백을 만나면 입력이 끝나므로 그 이후로는 출력이 되지 않는 문제점이 있다. 

cin.getline(address, 100, '\n'); //대신 cin.getline 이라는 맴버함수를 사용하면 공백을 포함한 문자열도 입력이 가능하다. 

cout << " 당신의 주소는 여기가 맞습니까 ? " << address << endl;

char city[21];

cout << " 도시를 입력하세요 : ";

cin.getline(city, 21, '.');

cout << " 입력한 도시는 " << city << endl;

return 0;

}




   (2) string클래스(사용방법, 예제)


string 클래스 란 C++ 표준 라이브러리에서 제공하는 클래스이며 이 클래스는 문자열의 크기에 제약이 없는 장점이 있다. 또한 문자열 복사, 비교 그리고 수정등과 같은 문자열 연산을 위한 맴버 함수와 연산자를 제공하기 때문에 더욱 쉽게 문자열을 다룰 수 있다.

아래 예제에서도 위의 예제와 달리 사이즈에 대한 부분이 없는 것을 확인 할 수 있다.


#include <cstdlib> 

#include <iostream>

#include <cstring>


using namespace std;


/* run this program using the console pauser or add your own getch, system("pause") or input loop */


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

//string 클래스 

string song("Falling in love with you");

string elvis("Elvis Presley");

string singer;

cout << song + "를 부른 가수는";

cout << "(힌트 : 첫글자는 " << elvis[0] << ")?";

getline(cin, singer);

if(singer == elvis)

cout << "맞았습니다."; 

else

cout << "틀렸습니다." + elvis + "입니다." << endl; 

return 0;


}



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

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

1. C++ 프로그래밍의 개발과정


C++ 언어로 구성된 프로그램의 개발 과정은 C++이 구현 되어져 있는 개발 도구에서 소스 프로그램을 작성한다. 

그 다음 해당 소스 프로그램이 작성 되어져 있는 파일을 컴파일 한다. 

컴파일을 하면 해당 소스 파일(.cpp)에서 목적 파일(.obj) 파일이 생성 되고 이 목적 파일에서 링킹 과정을 통해서 실행 파일(.exe)이 만들어진다. 

링킹 과정중에 C++ 라이브러리에서 참조하여 링킹 된다. 

실행시 오류가 발생하면 디버깅을 하기 위하여 다시 소스 프로그램을 수정하는 식으로 돌아가서 다시 컴파일을 한다.


2. 간단한 출력프로그램

   (출력소스, 실행결과, 주석: cout객체, namespace역활. std::의 의미 정리 )


#include <cstdlib>

#include <iostream>


using namespace std;


int main(int argc, char *argv[])

{

    std::cout << "Hello\n" << "첫번쨰 맛보기 입니다. " << endl;

    std::cout << "소프트웨어학과 PSB";


cout은 표준출력객체이다.

namespace는 말 그대로 이름공간 이라는 뜻으로 쉽게 생각할 수 있다.

예를들어 A회사와 B회사에 둘 다 C라는 이름을 가진 사람이 있으면 어떤 사람을 지칭하는지 중복이 되어 알기가 힘들기 때문에 사용해준다고 보면 된다.

이름 앞에 붙여진 std는 이름 공간이고 출력에 관여된 객체를 관리하고 있다.

:: 범위 지정 연산자는 소스코드나 이름공간 내의 함수나 변수를 지정하는데에 사용하는 연산자이다. 

std:: 는 std 이름공간안의 함수나 변수를 사용할수있게 지정한다는 것이다.  

 

     

    system("PAUSE");

    return EXIT_SUCCESS;



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

6. 함수중복과 static멤버  (0) 2018.05.15
5. 함수와 참조, 복사생성자  (0) 2018.05.03
4. 객체 포인터와 객체배열, 객체의 동적생성  (0) 2018.04.10
3. 클래스와 객체  (0) 2018.03.22
2. C++ 프로그래밍의 기본  (0) 2018.03.13

+ Recent posts