[모던C++입문] 6.1 기본 원칙
- 📕 Book/모던C++입문
- 2021. 7. 28.
6. 객채 지향 프로그래밍
6.1 기본 원칙
- 추상화(Abstraction) : 클래스는 개체의 특성과 멤버 함수를 정의, 클래스는 특성의 불변성을 지정할 수도 있음
- 캡슐화(Encapsulation) : 구현의 세부 사항을 숨기는 원칙. 내부 특성은 불변성을 위반하지 않기 위해 직접 접근 할 수 없으며, 클래스의 멤버 함수를 통해서만 접근할 수 있다.
- 상속(Inheritance) : 파생 클래스가 기본 클래스의 모든 멤버 변수와 멤버 함수를 포함한다는 원칙
- 다형성(Polymorphism) : 문맥이나 매개변수에 따라 해석하는 식별자의 능력
기본 클래스와 파생 클래스
class person
{
public:
person() { }
explicit person(const string& name) : name(name) { }
void set_name(const streing& n) { name = n; }
string get_name() const { return name; }
void all_info() const
{ cout << "[person] My name is " << name << endl; }
private:
string name;
}
class student : public person
{
public:
student(const string& name, const string& passed)
: person(name), passed(passed) { }
void all_info() const {
cout << "[student] My name is " << get_name() << endl;
cout << "I passed the following grades: " << passed << endl;
}
private:
string passed;
}
person mark("Mark Markson");
mark.all_info();
student tom("Tom Tomson", "Algebra, Analysis");
tom.all_info();
//p, pr, pp 는 전부 같음
person p(&tom);
person& pr = tom;
person* pp = &tom;
p.all_info();
pr.all_info();
pp->all_info();
//실행 결과
/*
[person] My name is Mark Markson
[student] My name is Tom Tomson
I passed the following grades : Algebra, Analysis
[person] My name is Tom Tomson
[person] My name is Tom Tomson
[person] My name is Tom Tomson
*/
생성자 상속
- 생성자는 기본 클래스에서 암시적으로 상속되지 않는 멤버함수
class person
{
public:
explicit person(const string& name) : name(name) { }
//...
};
class student : public person
{}; // string으로 정의된 생성자가 없다.
int main()
{
student tom("Tom Tomson"); //오류 : string 생성자가 없다
}
//C++11에서는 using을 통해 기본 클래스의 모든 생성자를 상속 받을수 있다.
class student : public person
{
using person::person;
};
가상 함수와 다형성 클래스
- 다형성 타입은 하나 이상의 가상 함수를 포함하는 클래스 이다.
- 다형성 타입은 항상 레퍼런스나 (스마트) 포인터로 전달해야 한다.
class person
{
virtual void all_info() const
{ cout << "[person] My name is " << name << endl; }
}
class student : public person
{
virtual void all_info() const
{
person::all_info(); //person클래스의 all_info를 호출
cout << "[student] My name is " << get_name() << endl;
cout << "I passed the following grades: " << passed << endl;
}
}
p.all_info();
pr.all_info();
pp->all_info();
//이전과 동일한 실행코드 출력 결과
/*
[person] My name is Tom Tomson
[person] My name is Tom Tomson
[student] My name is Tom Tomson
I passed the following grades: Algebra, Analysis
[person] My name is Tom Tomson
[student] My name is Tom Tomson
I passed the following grades: Algebra, Analysis
*/
명시적 오버라이딩
- C++11에서 추가된 override 특성을 사용하면 기본 클래스의 virtual 함수를 오버라이드 한다고 선언할 수 있다.
- C++11에서 추가된 다른 특성인 final은 가상 멤버 함수를 오버라이드 할 수 없다고 선언한다.
추상 클래스
- = 0 로 선언하는 virtual 함수를 순수 가상 함수(Pure Virtual Function)라고 한다.
- 순수 가상 함수를 포함하는 클래스를 추상 클래스(Abstract Class)라고 한다.
class creature
{
virtual void all_info() const = 0;
}
class person : public creature
{ ... }
int main()
{
creature som_beast; //오류 : 추상 클래스
}
상속을 통한 펑터
- 성능 : operator()는 항상 가상 함수로 호출된다.
- 적용 가능성: functor_base에서 파생된 클래스만 인수로 사용 가능
- 펑터는 가능하면 제네릭 방식을 사용해 구현해야한다.
struct functor_base
{
virtual double operator() (double x) const = 0;
};
double finite_difference(functor_base const& f, double x, double h)
{
return (f(x+h) - f(x)) / h;
}
class para_sin_plus_cos : public functor_base
{
public:
para_sin_plus_cos(double p) : alpha(p) { }
virtual double operaotr() (double x) const override
{ return sin(alpha * x) + cos(x); }
private:
double alpha;
}
int main()
{
para_sin_plus_cos sin_1(1.0);
cout << finite_difference(sin_1, 1., 0.001) << endl;
double df1 = finite_difference(para_sin_plus_cos(2.), 1., 0.001),
df0 = finite_difference(para_sin_plus_cos(2.),0., 0.001);
}
반응형