public , private, protected
상속시 제한자 설정
모든 변수가 설정한 제한자 보다 엄격히 보호됨
ex) private , protected , public 각가 존재 시
protected 로 상속
public 변수는 protected 로 강화
private 변수는 그대로 유지
-> 즉 부모 클래스의 접근 제한자를 그대로 유지하기 위해서는 public 을 사용한다.
#include<iostream>
using namespace std;
class base
{
private:
int Num_private;
protected:
int Num_protected;
public:
int Num_public;
base(): Num_private(1), Num_protected(2), Num_public(3)
{}
};
class Derived_private : private base
{
public:
Derived_private()
{
cout << "Derived_private" << endl;
//cout << "Num_private : "<< Num_private << endl;
//cout << "Num_protected : "<< Num_protected << endl;
//cout << "Num_public : "<< Num_public << endl;
}
};
class Derived_protected : protected base
{
public:
Derived_protected()
{
cout << "Derived_protected" << endl;
//cout << "Num_private : "<< Num_private << endl;
cout << "Num_protected : "<< Num_protected << endl;
cout << "Num_public : "<< Num_public << endl;
}
};
class Derived_public : public base
{
public:
Derived_public()
{
cout << "Derived_public" << endl;
//cout << "Num_private : "<< Num_private << endl;
cout << "Num_protected : " << Num_protected << endl;
cout << "Num_public : " << Num_public << endl;
}
};
int main()
{
Derived_private aDerived_private;
Derived_protected aDerived_protected;
Derived_public aDerived_public;
}
freind
일방적인 우정 -> 클래스 내부에 freind 로 설정한
위와 같은 freind 키워드는 특정 함수 , 특정 클래스에 대해서 지정할 수 있다.
사용 예제로는 무궁무진하지만, 2항 연산자의 오버라이딩에서 사용된다. ( -> 출처 블로그에서 공부해라)
#include<iostream>
using namespace std;
class parent
{
private :
int pNum;
friend void pfriend(parent aparent);
public :
parent() : pNum(1)
{
cout << "parent" << endl;
}
};
void pfriend(parent aparent)
{
cout << aparent.pNum << endl;
}
int main()
{
parent aparent;
pfriend(aparent);
}
virtual, override
1 . 상속의 override 개념
자식 클래스는 부모클래스의 함수나 변수를 덮어 쓸수 있다(override)
재미있는 점은 덮어써진 부모클래스의 변수나 , 함수는 자식클래스에서 접근할 수 없다.
#include<iostream>
using namespace std;
class parent
{
public :
int Num;
int Num1;
parent() : Num1(0),Num(1) {};
void test()
{
cout << "parent : " << Num <<endl;
};
};
class child : public parent
{
public:
int Num;
child() : Num(2) {};
void test()
{
cout << "child : " << Num << endl;
cout << "child : " << Num1 << endl;
};
};
int main()
{
parent aparent;
aparent.test();
child achild;
achild.test();
}
상속에서 재미있는 점은 부모 클래스의 포인터나 , 부모클래서의 래퍼런스는 자식 클래스의 변수를 지정할 수 있다.
#include<iostream>
using namespace std;
class parent
{
public :
int Num;
int Num1;
parent() : Num1(0),Num(1) {};
void test()
{
cout << "parent : " << Num <<endl;
};
};
class child : public parent
{
public:
int Num;
child() : Num(2) {};
void test()
{
cout << "child : " << Num << endl;
cout << "child : " << Num1 << endl;
};
};
int main()
{
parent aparent;
child achild;
parent* p;
p = &aparent;
(*p).test();
p = &achild;
(*p).test();
}
재미있는 점은 컴파일러는 parent 포인터로 받은 child 클래스를 parent 클래스로 인식하고 overide 되지 않은 함수를 호출 하는 것이다. 변수도 마찬가지
이를 해결 하기 위해서는 virtual 키워드를 사용한다.
#include<iostream>
using namespace std;
class parent
{
public :
int Num;
int Num1;
parent() : Num1(0),Num(1) {};
virtual void test()
{
cout << "parent : " << Num <<endl;
};
};
class child : public parent
{
public:
int Num;
child() : Num(2) {};
void test()override
{
cout << "child : " << Num << endl;
cout << "child : " << Num1 << endl;
};
};
int main()
{
parent aparent;
child achild;
parent* p;
p = &aparent;
(*p).test();
p = &achild;
(*p).test();
}
재미있는 점은 override 된 Num 변수 또한 override 된 변수로 동작한다 (어찌보면 당연하다)
override 키워드는 없어도 상관없으나 붙여주는것을 추천한다.
만약 virtual 함수가 아닌데 override 키워드를 붙이면 컴파일과정에서 에러 메세지를 표시해주기 때문에 , 가독성을 위해서도 , 만약을 대비한 에러를 위해서도 붙여주자.
또한 virtual 키워드를 사용한 클래스를 생성한다면 , virtual table 이나 포인터를 통해서 , 이를 구현하는데 이는 출처에서 나오는 블로그로 공부해보자.
출처:
댓글