인스턴스 aa가 접근할 수 있는 멤버변수 목록
#include <iostream>
using std::cout;
class A { // 기본 클래스, 부모 클래스
private:
void a1() {
cout << "a1\n";
}
void a2() {
cout << "a2\n";
}
public:
void b1() {
cout << "b1\n";
}
void b2() {
cout << "b2\n";
}
void b3() {
cout << "b3\n";
}
void b4() {
cout << "b4\n";
}
};
class B : public A {
};
int main() {
A aa;
aa.b1();
B bb;
bb.b1();
}
상속 방법
자식 클래스 : 접근 제어자 부모 클래스
A클래스의 public을 B클래스에 상속했으므로 bb.b1(); 가능하다
프로그래밍 언어들의 상속 방법
c++
class Base {
public:
void baseFunction() {}
};
class Derived : public Base {
public:
void derivedFunction() {}
};
java
class Base {
public void baseFunction() {}
}
class Derived extends Base {
public void derivedFunction() {}
}
c#
class Base {
public void BaseFunction() {}
}
class Derived : Base {
public void DerivedFunction() {}
}
python
class Base:
def baseFunction(self):
pass
class Derived(Base):
def derivedFunction(self):
pass
상속 구조
상속 접근제어
-private멤버는 상속불가
-부모클래스의 (public, protected) 멤버가 자식클래스로 넘어온다.
-3가지 상속 속성중에서 public을 가장 많이 씀
예제
B클래스가 A클래스를 상속 받았음
#include <iostream>
using std::cout;
using std::endl;
class A // 기본 클래스
{
int x;
public:
void setX(int i) { x = i; }
void showX() { cout << x << endl; }
};
class B :public A //파생 클래스
{
int y;
public:
void setY(int i) { y = i; }
void showY() { cout << y << endl; }
};
int main()
{
B bb; // 파생클래스의 객체
bb.setX(1); // 오류 ① bb.setX(1);
bb.setY(2); // 오류 ② bb.setY(2);
bb.showX(); // 기본클래스의 멤버접근
bb.showY(); // 파생클래스의 멤버접근
return 0;
}
private멤버는 상속 불가
bb.setX(1); 부모클래스 private 값을 변경
#include <iostream>
using std::cout;
using std::endl;
class A
{
int x; // private 속성이 생략됨
public:
void setX(int i) { x = i; }
void showX() { cout << x << endl; }
};
class B :public A
{
int y;
public:
void setY(int i) { y = i; }
void showXY() { showX(); cout << y << endl; }
};
int main()
{
B bb;
bb.setX(1); // 기본클래스의 멤버접근
bb.setY(2); // 파생클래스의 멤버접근
bb.showX(); // 기본클래스의 멤버접근
bb.showXY(); // 파생클래스의 멤버접근
return 0;
}
부모의 private멤버 접근은 get함수를 써야함
상속 속성이 private인 경우
private멤버는 상속 불가
public, protected 멤버는 private으로 바꿔서 상속된다.
#include <iostream>
using std::cout;
using std::endl;
class A
{
int x; //int x=10; //가능?
public:
void setX(int i) { x = i; }
void showX() { cout << x << endl; }
};
class B :private A //비공개적으로 상속
{
int y;
public:
void setY(int i) { y = i; }
void showY() { cout << y << endl; }
};
int main()
{
A aa;
B bb;
aa.setX(1);
aa.showX();
bb.setX(1); // 오류
bb.setY(2); // 파생클래스의 멤버접근
bb.showX(); // 오류
bb.showY(); // 파생클래스의 멤버접근
return 0;
}
오류 나는 이유는 private으로 상속해서 외부에서 접근 할 수 없고 자식클래스 내부에서만 사용 가능하다.
private 속성으로 상속받은 자식클래스는 부모클래스의 함수를 내부에서만 사용할 수 있다.
클래스 내부에서 멤버변수 초기화 방법(비추)
#include <iostream>
using std::cout;
using std::endl;
class A
{
int x = 1;// In-class member initializers
public:
void setX(int i) { x = i; }
int getX() { return x; }
};
int main()
{
A a1; //디폴트 생성자 호출, 눈에 안보이는 A(){}
cout << a1.getX() << endl;
return 0;
}
//1
#include <iostream>
using std::cout;
using std::endl;
class A
{
int x = 1;
public:
A() { x = 2; } //
A():x(2){}
void setX(int i) { x = i; }
int getX() { return x; }
};
int main()
{
A a1; //디폴트 생성자는 사라짐
cout << a1.getX() << endl;
return 0;
}
//2
생성자 정의 방법
1. A() { x = 2; }
2. A():x(2){}
protected 상속
protected 접근제어속성 특징
-자식에게 상속됨
-외부에서 접근 할 수 없음
private속성은 멤버변수를 상속 할 수 없지만 protected속성은 멤버변수를 상속 할 수 있으므로 상속을 할 경우 protected속성으로 하는것이 좋음
#include <iostream>
using std::cout;
using std::endl;
class A
{
protected: //private이라면?
int a, b;
public:
void setAB(int i, int j) { a = i; b = j; }
};
class B :public A
{
int c; // private
public:
void setC(int n) { c = n; }
void showABC() { cout << a << b << c << endl; }
//기본 클래스의 protected 멤버들은
//파생 클래스의 멤버에 의해 접근될 수 있다.
};
int main()
{
A aa;
B bb;
//aa.a; //외부에서는 접근불가
//bb.b; //외부에서는 접근불가
bb.setAB(1, 2);
bb.setC(3);
bb.showABC();
return 0;
}
가장 많이 사용하는 방식
상속에서 생성자와 소멸자
#include <iostream>
using std::cout;
class A
{
public:
A() { cout << "A의 생성자\n"; }
~A() { cout << "A의 소멸자\n"; }
};
class B :public A
{
public:
B() { cout << "B의 생성자\n"; }
~B() { cout << "B의 소멸자\n"; }
};
int main()
{
B ob;
return 0;
}
생성자는 부모의 생성자가 호출되고 자식의 생성자가 호출된다.
소멸자는 자식의 소멸자가 호출되고 부모의 소멸자가 호출된다.
#include <iostream>
using std::cout;
using std::endl;
class A //할아버지
{
int a;
public:
A(int i) { a = i; }
int getA() { return a; }
};
class B :public A //아버지
{
int b;
public:
B(int i, int j) :A(i) {
// i는 기본 클래스 A의
//생성자 매개변수로 전달됨
b = j;
}
int getB() { return b; }
};
class C :public B //자식
{
int c;
public:
C(int i, int j, int k) :B(i, j) {
// i, j는 클래스 B의 생성자 매개변수로 전달됨
c = k;
}
void show() {
cout << getA() << ' ' << getB() << ' ' << c << endl;
}
};
int main()
{
C cc(10, 20, 30);
cc.show();
cout << cc.getA() << ' ' << cc.getB() << endl;
return 0;
}
#include <iostream>
using std::cout;
using std::endl;
class B { //할아버지
double d;
public:
B(double dd) { d = dd; }
double getD() { return d; }
};
class D1 :public B { //아버지
int i;
public:
D1(double dd, int ii) :B(dd) { i = ii; }
int getI() { return i; }
};
class D2 :public D1 { //자식
char c;
public:
D2(double dd, int ii, char cc) :D1(dd, ii) { c = cc; }
void print() {
cout << "Double : " << getD() << endl;
// B 멤버 호출
cout << "Int : " << getI() << endl;
// D1 멤버 호출
cout << "Char : " << c << endl;
}
};
int main()
{
D2 d2(10.5, 10, 'H');
cout << d2.getD() << ',' << d2.getI() << endl;
// B, D1 멤버 호출
d2.print();
return 0;
}
이 소스는 한성현 교수님 소스를 수정했습니다.
'C++' 카테고리의 다른 글
C++ 프로그래밍 14주차 (1) | 2023.12.06 |
---|---|
C++프로그래밍 13주차 (1) | 2023.11.29 |
C+프로그래밍 11주차 (0) | 2023.11.15 |
C++프로그래밍 10주차 (0) | 2023.11.08 |
C++ 프로그래밍 9주차 (0) | 2023.11.01 |