Programming/C++

[C++] 상속

Jubil 2018. 1. 22. 20:38
반응형

<클래스 상속>


이미 정의된 클래스의 멤버를 새롭게 정의할 클래스의 멤버로 참조케 하는 것을 말합니다.


즉, 이미 작성한 클래스의 멤버를 물려받는 것입니다.


부모 클래스/기반 클래스 와 자식 클래스/파생 클래스  라고 얘기합니다.



class 자식클래스 : 접근지정자 부모클래스

{

멤버 변수와 함수 선언;

};


자식 클래스의 객체는 부모 클래스의 멤버를 새롭게 정의하지 않아도 멤버 참조가 가능합니다. (private 제외)




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <string>
using namespace std;
 
class Figure                            //부모 클래스
{
public:
    void setColor(const string color);
    string getColor();
 
private:
    string color;
};
 
class Circle : public Figure            //자식 클래스
{
    void setRadius(const double r);
    double getArea();
 
private:
    double radius, area;
};
 
 
int main() {
    Figure f;
    Circle c;
}
cs


이렇게 Circle class는 Figure class를 상속 받고 있습니다.


Circle class의 객체인 c는 당연히 setRadius(), getArea(), radius, area를 참조할 수 있습니다.

또한 부모 class의 setColor(), getColor()를 참조할 수 있습니다. private인 color는 Figure의 객체에서만 참조할 수 있습니다.


Figure class의 객체인 f는 setColor(), getColor(), color를 참조할 수 있지만, 자식 class의 멤버 변수나, 멤버 함수는 참조할 수 없습니다.




<함수 오버라이딩>


부모 클래스의 멤버 함수를 자식 클래스에서 다시 정의하는 것을 말합니다.




- 동적 결합


실행 시 호출될 함수를 결정하는 것으로 하나의 함수가 여러 클래스에서 오버라이딩 되었을 때 사용합니다.



- 다형성


하나의 함수가 여러 구현 형태로 정의되는 것입니다.


다형성에 의해 함수 재정의시 요구 조건은 부모 클래스의 멤버 함수가 가상함수로 선언되어 있어야 하고, 매개변수로 전달된 변수는 객체의 주소를 포함해야 하는 것입니다.



- 가상 함수


함수 오버라이딩을 목적으로한 부모 클래스의 함수입니다.


virtual 반환형 함수이름();


이렇게 선언합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
using namespace std;
 
class A
{
public:
    string classMessage() {
        return "class A";
    }
};
 
class B : public A
{
public:
    string classMessage() {
        return "class B";
    }
};
 
void TestFunc(A x) {
    cout << x.classMessage() << endl;
}
 
 
int main() {
    A a;
    B b;
 
    TestFunc(a);
    TestFunc(b);
 
    return 0;
}
cs




실행 결과는 이렇습니다.


객체 b를 넘겨줬고, 함수는 오버라이딩 되어서 호출했을 때 class B의 classMessage() 함수를 호출할 거라고 생각했지만, 결과는 class A가 두 번 출력되었습니다.



매개 변수에 class A를 따르는 객체를 받아와서 class A에서만 참조하기 때문입니다. 그래서 자식 클래스를 절달해도 해당 클래스의 함수를 호출한 것입니다.



그럼 동적 결합을 해야하는데요.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
using namespace std;
 
class A
{
public:
    virtual string classMessage() {
        return "class A";
    }
};
 
class B : public A
{
public:
    string classMessage() {
        return "class B";
    }
};
 
void TestFunc(A *x) {
    cout << x->classMessage() << endl;
}
 
 
int main() {
    A a;
    B b;
 
    TestFunc(&a);
    TestFunc(&b);
 
    return 0;
}
cs


A class의 함수를 가상 함수로 만들어서 다형성을 지원해줍니다.


그리고 매개 변수로 객체의 주소를 받고, 포인터이기 때문에 . 연산자가 아닌 -> 연산자를 사용했습니다.


그러면 동적 결합이 잘 돼서 우리가 원하는 결과가 출력됩니다.






<추상 클래스>


객체 생성이 목적이 아닌 클래스입니다.


상속에서 부모 클래스 역할을 담당하고 순수 가상 함수를 포함합니다.



- 순수 가상 함수


함수 내용을 정의하지 않고 자식 클래스에서 함수 오버라이딩에 의해 내용이 결정되는 형태의 함수입니다.


virtual 반환형 함수이름() = 0;


이렇게 선언합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string>
using namespace std;
 
class AbstractClass
{
public:
    virtual string SampleFunction() = 0;
};
 
class TestClass : public AbstractClass
{
public:
    string SampleFunction() {
        return "SampleFunction";
    }
};
 
 
int main() {
    AbstractClass obj1;                        //추상 클래스는 객체를 생성하지 못해서 error
 
    cout << obj1.SampleFunction() << endl;
 
    return 0;
}
cs


추상 클래스는 객체를 생성하지 못합니다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string>
using namespace std;
 
class AbstractClass
{
public:
    virtual string SampleFunction() = 0;
};
 
class TestClass : public AbstractClass
{
public:
    string SampleFunction() {
        return "SampleFunction";
    }
};
 
 
int main() {
    TestClass obj1;
 
    cout << obj1.SampleFunction() << endl;
 
    return 0;
}
cs


error가 발생하지 않습니다.



실행해보면 결과가 잘 출력됩니다.



추상 클래스는 아직 너무 추상적이여서 객체화 할 수 없을 때 사용합니다.

반응형

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

[C++] 파일 입출력 fstream  (0) 2018.01.22
[C++] string 클래스  (0) 2018.01.22
[C++] this  (0) 2018.01.22
[C++] 객체 포인터  (0) 2018.01.22
[C++] 소멸자  (0) 2018.01.22