#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 { }; //class B : public A { }; //파생클래스, 자식클래스
int main() {
A aa;
aa.b1(); // b1 출력
B bb;
bb. //아무것도 뜨지않음
return 0;
}
↓ 상속 추가
#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 { //상속
}; //class B : public A { }; //파생클래스, 자식클래스
int main() {
A aa;
aa.b1(); // b1 출력
B bb;
bb. // A의 public클래스에 있는 것들이 뜸
return 0;
}
- 상속을 하게되면 부모의 public울 받아와 사용할 수 있다.
#include <iostream> // 표준 입출력 라이브러리 포함
using std::cout; // cout을 std 네임스페이스에서 사용
// 클래스 A 정의 - 기본 클래스(부모 클래스)
class A {
private:
// private 멤버 함수 - 클래스 외부에서 접근 불가
void a1() { cout << "a1\n"; } // a1 함수 정의
void a2() { cout << "a2\n"; } // a2 함수 정의
public:
// public 멤버 함수 - 클래스 외부에서 접근 가능
void b1() { cout << "b1\n"; } // b1 함수 정의
void b2() { cout << "b2\n"; } // b2 함수 정의
void b3() { cout << "b3\n"; } // b3 함수 정의
void b4() { cout << "b4\n"; } // b4 함수 정의
};
// 클래스 B 정의 - 클래스 A를 상속받는 파생 클래스(자식 클래스)
class B : public A {
// B 클래스는 A 클래스의 모든 public 및 protected 멤버에 접근 가능
}; // class B : public A { };
int main() {
A aa; // 클래스 A의 객체 aa 생성
aa.b1(); // aa 객체를 통해 b1 호출, "b1" 출력
B bb; // 클래스 B의 객체 bb 생성
bb.b1(); // b1은 A 클래스의 public 멤버이므로 접근 가능하지만, B 클래스의 bb 객체로는 접근 불가
// 이 부분에서 b1 호출 시 컴파일 오류 발생
return 0; // 프로그램 종료
}
- 객체지향언어의의 특징 3가지
- 캡슐화
- 다형성
- 상속성
1. 상속(inheritance)
다양한 언어로 보는 간단한 예제
- python
class Animal:
def sound(self):
print("Animal sound")
class Dog(Animal):
def sound(self):
print("Bark")
dog = Dog()
dog.sound() # "Bark" 출력
- java
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // "Bark" 출력
}
}
- javascript
class Animal {
sound() {
console.log("Animal sound");
}
}
class Dog extends Animal {
sound() {
console.log("Bark");
}
}
const dog = new Dog();
dog.sound(); // "Bark" 출력
▶ 상속 과정
- 계층적으로 상속을 받게 되면 기존의 클래스를 그대로 사용할 수 있는 장점이 있고 또한 새로운 클래스를 보다 쉽게 만들 수 있다.

▶ 기본클래스와 파생클래스 : is-a, is_a, is a 관계

is a = 상속
▶클래스 상속 형식

1) public 상속 접근제어
▶ 상속 접근제어 속성에 따른 파생 클래스 멤버의 속성변화

- 상속 접근 제어:
- 표의 맨 위에는 class Dog : public Animal이라는 문구가 있다. 이는 Dog 클래스가 Animal 클래스를 public으로 상속받고 있음을 나타낸다.
- 기본 클래스의 속성:
- 표의 첫 번째 열은 기본 클래스 Animal의 멤버 접근 제어를 나타낸다. 각 행은 private, protected, public의 세 가지 접근 수준을 보여준다.
- 접근 제어 규칙:
- 각 셀은 Dog 클래스에서 접근할 수 있는지를 나타낸다.
예를 들어- private: 기본 클래스에서 private로 선언된 멤버는 파생 클래스에서 접근할 수 없다. (모든 경우에서 "접근 불가")
- protected: 기본 클래스에서 protected로 선언된 멤버는 public 상속을 통해 파생 클래스에서 protected로 접근할 수 있다. (즉, Dog 클래스에서 접근 가능하지만 외부에서는 접근 불가)
- public: 기본 클래스에서 public으로 선언된 멤버는 public 상속을 통해 파생 클래스에서도 public으로 접근할 수 있다. (즉, Dog 클래스의 인스턴스에서 접근 가능)
- 기본클래스의 모든 public, protected 멤버들은 파생 클래스의 public, protected멤버가 됨
- 기본클래스의 private 멤버는 private 멤버로 남고, 파생 클래스의 의해서 접근될 수 없다.
- 각 셀은 Dog 클래스에서 접근할 수 있는지를 나타낸다.

▷ public 상속 접근제어로 상속
#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 showY() { cout << y << endl; }
};
int main()
{
B bb; // 파생클래스의 객체
bb.x = 1; // 오류 ① bb.setX(1); //부모의 private는 접근 불가능
bb.y = 2; // 오류 ② bb.setY(2);
bb.showX(); // 기본클래스의 멤버접근
bb.showY(); // 파생클래스의 멤버접근
return 0;
}
▷ public 상속 접근제어로 상속2
#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
showXY() { cout << x << y << endl; } //x에서 오류 발생 : 자식이 부모의 private에 접근해서
};
int main()
{
B bb;
bb.setX(1); // 기본클래스의 멤버접근
bb.setY(2); // 파생클래스의 멤버접근
bb.showX(); // 기본클래스의 멤버접근
bb.showXY(); // 파생클래스의 멤버접근
return 0;
}
class B :public A
{
int y;
public:
void setY(int i) { y = i; }
void
showXY() { cout << showX << y << endl; } //오류 수정
};
2) private 상속 접근제어


- private으로 상속하게되면 그대로 상속되는것이 아니고 자식의 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;
// private 상속을 하면 이쪽. 부모에서 public이었던 것도 자식의 private에 상속되기 때문에 외부에서 접근 불가능
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 상속을 하면 부모에서 public이었던 것도 자식의 private에 상속되기 때문에 외부에서 접근 불가능
▶ In-class member initializer
#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;
}
#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; // 2 출력
return 0;
}
A() { x = 2; } = A():x(2){}
3) protected 상속 제어접근
public vs , proticted
공통점 : 외부에서 접근이 바로 안된다.
▷ 상속에서 생성자와 소멸자
#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;
}
//실제 B 클래스의 구성
class B :public A
{
public:
A() { cout << "A의 생성자 "; }
~A() { cout << "A의 소멸자 "; }
B() { cout << "B의 생성자 "; }
~B() { cout << "B의 소멸자 "; }
};
부모 클래스 생성자 -> 자식 클래스 생성자
자식 클래스 생성자 -> 부모 클래스 생성자
▷ 파생 클래스 생성자에서 기본 클래스 생성자에 매개변수 전달 형식
#include <iostream>
using std::cout;
using std::endl;
class A {
int a;
public:
A(int i) {
cout << "A의 생성자\n";
a = i;
}
~A() { cout << "A의 소멸자\n"; }
void showA() { cout << a << '\n'; }
};
class B :public A {
int b;
public:
B(int i, int j) :A(i) {// i는 기본클래스 생성자의 매개변수로 전달
cout << "B의 생성자\n";
b = j;
}
~B() { cout << "B의 소멸자\n"; }
void showB() { cout << b << endl; }
};
int main()
{
B bb(10, 20);
bb.showA();
bb.showB();
return 0;
}

4) 계층적 다중 상속
- 자식 클래스가 여러 개의 기본 클래스를 상속 받을 수 있다.
- 할아버지 클래스로부터 아버지 클래스를 상속 받고, 아버지 클래스로부터 자식 클래스가 상속
#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;
}
//10 20 30
//10 20
//출력
5) 여러 개 의 기본 클래스를 동시에 상속
- 아버지와 어머니 클래스를 아들 클래스가 물려 받는 것 ( java, c#, svift 등에선 지원하지 않음 대신 비슷하게 동작하는 다른 게 있음)

▷ 2개의 기본 클래스 상속
#include <iostream>
using std::cout;
using std::endl;
class A1 // 아버지
{
int a;
public:
A1(int i) { a = i; }
int getA() { return a; }
};
class A2 // 어머니
{
int b;
public:
A2(int i) { b = i; }
int getB() { return b; }
};
class B :public A1, public A2
{
// 기본 클래스 A1과 A2로부터
// 상속 받은 파생 클래스
int c;
public:
B(int i, int j, int k) :A1(i), A2(j) { c = k; }
// i는 기본클래스 A1의 생성자로,
// j는 기본클래스 A2의 생성자로
// 각각 매개변수 전달
void show() {
cout << getA() << ' ' << getB() << ' ' << c << endl;
}
};
int main()
{
B bb(1, 2, 3);
bb.show();
return 0;
}
// 1 2 3 출력

//둘다 사람이고 이름이 있네? -> 사람 클래스를 먼저 만들어서 이름과 나이 넣고 자식으로 학생과 교수를 만들어야겠다.
- Man 클래스 생성
#include <iostream>
using std::cout;
using std::endl;
using std::string;
//사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
class Man {
protected:
string name;
int age;
};
//멤버변수를 초기화하는 생성자를 구현하시오.
//기타 함수를 구현하시오.
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오. (멤버변수:반, 학번), 생성자, 기타함수
//사람클래스로부터 상속받은 교수(Teacher)클래스를 만드시오. (멤버변수:전공, 담당과목), 생성자, 기타함수
//main함수에서 학생객체와, 교수객체를 만들어 테스트해보시오.
//int main()
//{
// Student kks("김컴소", 20, "C반", "202012000");
// Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
// kks.s_show();
// hsh.t_show();
// return 0;
//}
- 생성자 구형, 기타함수 구현 -> 부모클래스 완성
#include <iostream>
using std::cout;
using std::endl;
using std::string;
//사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
class Man {
protected:
string name;
int age;
public:
Man(string n, int a) { //멤버변수를 초기화하는 생성자를 구현하시오.
name = n;
age = a;
}
void m_show() { //기타 함수를 구현하시오. -> show()
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
};
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오. (멤버변수:반, 학번), 생성자, 기타함수
//사람클래스로부터 상속받은 교수(Teacher)클래스를 만드시오. (멤버변수:전공, 담당과목), 생성자, 기타함수
//main함수에서 학생객체와, 교수객체를 만들어 테스트해보시오.
//int main()
//{
// Student kks("김컴소", 20, "C반", "202012000");
// Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
// kks.s_show();
// hsh.t_show();
// return 0;
//}
- Student 클래스 완성
#include <iostream>
using std::cout;
using std::endl;
using std::string;
//사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
class Man {
protected: //상속할거라서 protected
string name;
int age;
public:
Man(string n, int a) { //멤버변수를 초기화하는 생성자를 구현하시오.
name = n;
age = a;
}
void m_show() { //기타 함수를 구현하시오. -> show()
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
};
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오. (멤버변수:반, 학번), 생성자, 기타함수
class Student : public Man {
private:
string ban;
string hak;
public:
Student(string n, int a, string b, string h) : Man(n,a) {
ban = b;
hak = h;
}
void s_show() {
m_show();
cout << "반 : " << ban << endl;
cout << "학번 : " << hak << endl;
}
};
//사람클래스로부터 상속받은 교수(Teacher)클래스를 만드시오. (멤버변수:전공, 담당과목), 생성자, 기타함수
class Teacher : public Man {
};
//main함수에서 학생객체와, 교수객체를 만들어 테스트해보시오.
int main()
{
Student kks("김컴소", 20, "C반", "202012000");
// Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
kks.s_show();
// hsh.t_show();
return 0;
}
//이름: 김컴소
//나이 : 20
//반 : C반
//학번 : 202012000
#include <iostream>
using std::cout;
using std::endl;
using std::string;
//사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
class Man {
protected: //상속할거라서 protected
string name;
int age;
public:
Man(string n, int a) { //멤버변수를 초기화하는 생성자를 구현하시오.
name = n;
age = a;
}
void m_show() { //기타 함수를 구현하시오. -> show()
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
};
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오. (멤버변수:반, 학번), 생성자, 기타함수
class Student : public Man {
private:
string ban;
string hak;
public:
Student(string n, int a, string b, string h) : Man(n,a) {
ban = b;
hak = h;
}
void s_show() {
m_show();
cout << "반 : " << ban << endl;
cout << "학번 : " << hak << endl;
}
};
//사람클래스로부터 상속받은 교수(Teacher)클래스를 만드시오. (멤버변수:전공, 담당과목), 생성자, 기타함수
class Teacher : public Man {
private:
string major; // 전공
string sub; // 담당 과목
public:
// 생성자에서 Teacher로 이름을 변경
Teacher(string n, int a, string m, string s) : Man(n, a) {
major = m;
sub = s;
}
void t_show() {
m_show();
cout << "전공 : " << major << endl;
cout << "과목 : " << sub << endl;
}
};
//main함수에서 학생객체와, 교수객체를 만들어 테스트해보시오.
int main()
{
Student kks("김컴소", 20, "C반", "202012000");
Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
kks.s_show();
hsh.t_show();
return 0;
}
//이름: 김컴소
//나이 : 20
//반 : C반
//학번 : 202012000
'C++' 카테고리의 다른 글
13. 바인딩, 오버로딩/오버라이 가상함수 (0) | 2024.11.26 |
---|---|
11. 함수 중첩, 디폴트 인자 (0) | 2024.11.12 |
8. const 동적 메모리 할당 (new, delete) (8) | 2024.11.05 |
7. 객체와 멤버, 생성자/소멸자, this 포인터 (0) | 2024.10.29 |
6. 접근 속성 클래스와 객체 만들기 (2) | 2024.10.15 |
#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 { }; //class B : public A { }; //파생클래스, 자식클래스
int main() {
A aa;
aa.b1(); // b1 출력
B bb;
bb. //아무것도 뜨지않음
return 0;
}
↓ 상속 추가
#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 { //상속
}; //class B : public A { }; //파생클래스, 자식클래스
int main() {
A aa;
aa.b1(); // b1 출력
B bb;
bb. // A의 public클래스에 있는 것들이 뜸
return 0;
}
- 상속을 하게되면 부모의 public울 받아와 사용할 수 있다.
#include <iostream> // 표준 입출력 라이브러리 포함
using std::cout; // cout을 std 네임스페이스에서 사용
// 클래스 A 정의 - 기본 클래스(부모 클래스)
class A {
private:
// private 멤버 함수 - 클래스 외부에서 접근 불가
void a1() { cout << "a1\n"; } // a1 함수 정의
void a2() { cout << "a2\n"; } // a2 함수 정의
public:
// public 멤버 함수 - 클래스 외부에서 접근 가능
void b1() { cout << "b1\n"; } // b1 함수 정의
void b2() { cout << "b2\n"; } // b2 함수 정의
void b3() { cout << "b3\n"; } // b3 함수 정의
void b4() { cout << "b4\n"; } // b4 함수 정의
};
// 클래스 B 정의 - 클래스 A를 상속받는 파생 클래스(자식 클래스)
class B : public A {
// B 클래스는 A 클래스의 모든 public 및 protected 멤버에 접근 가능
}; // class B : public A { };
int main() {
A aa; // 클래스 A의 객체 aa 생성
aa.b1(); // aa 객체를 통해 b1 호출, "b1" 출력
B bb; // 클래스 B의 객체 bb 생성
bb.b1(); // b1은 A 클래스의 public 멤버이므로 접근 가능하지만, B 클래스의 bb 객체로는 접근 불가
// 이 부분에서 b1 호출 시 컴파일 오류 발생
return 0; // 프로그램 종료
}
- 객체지향언어의의 특징 3가지
- 캡슐화
- 다형성
- 상속성
1. 상속(inheritance)
다양한 언어로 보는 간단한 예제
- python
class Animal:
def sound(self):
print("Animal sound")
class Dog(Animal):
def sound(self):
print("Bark")
dog = Dog()
dog.sound() # "Bark" 출력
- java
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // "Bark" 출력
}
}
- javascript
class Animal {
sound() {
console.log("Animal sound");
}
}
class Dog extends Animal {
sound() {
console.log("Bark");
}
}
const dog = new Dog();
dog.sound(); // "Bark" 출력
▶ 상속 과정
- 계층적으로 상속을 받게 되면 기존의 클래스를 그대로 사용할 수 있는 장점이 있고 또한 새로운 클래스를 보다 쉽게 만들 수 있다.

▶ 기본클래스와 파생클래스 : is-a, is_a, is a 관계

is a = 상속
▶클래스 상속 형식

1) public 상속 접근제어
▶ 상속 접근제어 속성에 따른 파생 클래스 멤버의 속성변화

- 상속 접근 제어:
- 표의 맨 위에는 class Dog : public Animal이라는 문구가 있다. 이는 Dog 클래스가 Animal 클래스를 public으로 상속받고 있음을 나타낸다.
- 기본 클래스의 속성:
- 표의 첫 번째 열은 기본 클래스 Animal의 멤버 접근 제어를 나타낸다. 각 행은 private, protected, public의 세 가지 접근 수준을 보여준다.
- 접근 제어 규칙:
- 각 셀은 Dog 클래스에서 접근할 수 있는지를 나타낸다.
예를 들어- private: 기본 클래스에서 private로 선언된 멤버는 파생 클래스에서 접근할 수 없다. (모든 경우에서 "접근 불가")
- protected: 기본 클래스에서 protected로 선언된 멤버는 public 상속을 통해 파생 클래스에서 protected로 접근할 수 있다. (즉, Dog 클래스에서 접근 가능하지만 외부에서는 접근 불가)
- public: 기본 클래스에서 public으로 선언된 멤버는 public 상속을 통해 파생 클래스에서도 public으로 접근할 수 있다. (즉, Dog 클래스의 인스턴스에서 접근 가능)
- 기본클래스의 모든 public, protected 멤버들은 파생 클래스의 public, protected멤버가 됨
- 기본클래스의 private 멤버는 private 멤버로 남고, 파생 클래스의 의해서 접근될 수 없다.
- 각 셀은 Dog 클래스에서 접근할 수 있는지를 나타낸다.

▷ public 상속 접근제어로 상속
#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 showY() { cout << y << endl; }
};
int main()
{
B bb; // 파생클래스의 객체
bb.x = 1; // 오류 ① bb.setX(1); //부모의 private는 접근 불가능
bb.y = 2; // 오류 ② bb.setY(2);
bb.showX(); // 기본클래스의 멤버접근
bb.showY(); // 파생클래스의 멤버접근
return 0;
}
▷ public 상속 접근제어로 상속2
#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
showXY() { cout << x << y << endl; } //x에서 오류 발생 : 자식이 부모의 private에 접근해서
};
int main()
{
B bb;
bb.setX(1); // 기본클래스의 멤버접근
bb.setY(2); // 파생클래스의 멤버접근
bb.showX(); // 기본클래스의 멤버접근
bb.showXY(); // 파생클래스의 멤버접근
return 0;
}
class B :public A
{
int y;
public:
void setY(int i) { y = i; }
void
showXY() { cout << showX << y << endl; } //오류 수정
};
2) private 상속 접근제어


- private으로 상속하게되면 그대로 상속되는것이 아니고 자식의 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;
// private 상속을 하면 이쪽. 부모에서 public이었던 것도 자식의 private에 상속되기 때문에 외부에서 접근 불가능
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 상속을 하면 부모에서 public이었던 것도 자식의 private에 상속되기 때문에 외부에서 접근 불가능
▶ In-class member initializer
#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;
}
#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; // 2 출력
return 0;
}
A() { x = 2; } = A():x(2){}
3) protected 상속 제어접근
public vs , proticted
공통점 : 외부에서 접근이 바로 안된다.
▷ 상속에서 생성자와 소멸자
#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;
}
//실제 B 클래스의 구성
class B :public A
{
public:
A() { cout << "A의 생성자 "; }
~A() { cout << "A의 소멸자 "; }
B() { cout << "B의 생성자 "; }
~B() { cout << "B의 소멸자 "; }
};
부모 클래스 생성자 -> 자식 클래스 생성자
자식 클래스 생성자 -> 부모 클래스 생성자
▷ 파생 클래스 생성자에서 기본 클래스 생성자에 매개변수 전달 형식
#include <iostream>
using std::cout;
using std::endl;
class A {
int a;
public:
A(int i) {
cout << "A의 생성자\n";
a = i;
}
~A() { cout << "A의 소멸자\n"; }
void showA() { cout << a << '\n'; }
};
class B :public A {
int b;
public:
B(int i, int j) :A(i) {// i는 기본클래스 생성자의 매개변수로 전달
cout << "B의 생성자\n";
b = j;
}
~B() { cout << "B의 소멸자\n"; }
void showB() { cout << b << endl; }
};
int main()
{
B bb(10, 20);
bb.showA();
bb.showB();
return 0;
}

4) 계층적 다중 상속
- 자식 클래스가 여러 개의 기본 클래스를 상속 받을 수 있다.
- 할아버지 클래스로부터 아버지 클래스를 상속 받고, 아버지 클래스로부터 자식 클래스가 상속
#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;
}
//10 20 30
//10 20
//출력
5) 여러 개 의 기본 클래스를 동시에 상속
- 아버지와 어머니 클래스를 아들 클래스가 물려 받는 것 ( java, c#, svift 등에선 지원하지 않음 대신 비슷하게 동작하는 다른 게 있음)

▷ 2개의 기본 클래스 상속
#include <iostream>
using std::cout;
using std::endl;
class A1 // 아버지
{
int a;
public:
A1(int i) { a = i; }
int getA() { return a; }
};
class A2 // 어머니
{
int b;
public:
A2(int i) { b = i; }
int getB() { return b; }
};
class B :public A1, public A2
{
// 기본 클래스 A1과 A2로부터
// 상속 받은 파생 클래스
int c;
public:
B(int i, int j, int k) :A1(i), A2(j) { c = k; }
// i는 기본클래스 A1의 생성자로,
// j는 기본클래스 A2의 생성자로
// 각각 매개변수 전달
void show() {
cout << getA() << ' ' << getB() << ' ' << c << endl;
}
};
int main()
{
B bb(1, 2, 3);
bb.show();
return 0;
}
// 1 2 3 출력

//둘다 사람이고 이름이 있네? -> 사람 클래스를 먼저 만들어서 이름과 나이 넣고 자식으로 학생과 교수를 만들어야겠다.
- Man 클래스 생성
#include <iostream>
using std::cout;
using std::endl;
using std::string;
//사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
class Man {
protected:
string name;
int age;
};
//멤버변수를 초기화하는 생성자를 구현하시오.
//기타 함수를 구현하시오.
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오. (멤버변수:반, 학번), 생성자, 기타함수
//사람클래스로부터 상속받은 교수(Teacher)클래스를 만드시오. (멤버변수:전공, 담당과목), 생성자, 기타함수
//main함수에서 학생객체와, 교수객체를 만들어 테스트해보시오.
//int main()
//{
// Student kks("김컴소", 20, "C반", "202012000");
// Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
// kks.s_show();
// hsh.t_show();
// return 0;
//}
- 생성자 구형, 기타함수 구현 -> 부모클래스 완성
#include <iostream>
using std::cout;
using std::endl;
using std::string;
//사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
class Man {
protected:
string name;
int age;
public:
Man(string n, int a) { //멤버변수를 초기화하는 생성자를 구현하시오.
name = n;
age = a;
}
void m_show() { //기타 함수를 구현하시오. -> show()
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
};
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오. (멤버변수:반, 학번), 생성자, 기타함수
//사람클래스로부터 상속받은 교수(Teacher)클래스를 만드시오. (멤버변수:전공, 담당과목), 생성자, 기타함수
//main함수에서 학생객체와, 교수객체를 만들어 테스트해보시오.
//int main()
//{
// Student kks("김컴소", 20, "C반", "202012000");
// Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
// kks.s_show();
// hsh.t_show();
// return 0;
//}
- Student 클래스 완성
#include <iostream>
using std::cout;
using std::endl;
using std::string;
//사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
class Man {
protected: //상속할거라서 protected
string name;
int age;
public:
Man(string n, int a) { //멤버변수를 초기화하는 생성자를 구현하시오.
name = n;
age = a;
}
void m_show() { //기타 함수를 구현하시오. -> show()
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
};
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오. (멤버변수:반, 학번), 생성자, 기타함수
class Student : public Man {
private:
string ban;
string hak;
public:
Student(string n, int a, string b, string h) : Man(n,a) {
ban = b;
hak = h;
}
void s_show() {
m_show();
cout << "반 : " << ban << endl;
cout << "학번 : " << hak << endl;
}
};
//사람클래스로부터 상속받은 교수(Teacher)클래스를 만드시오. (멤버변수:전공, 담당과목), 생성자, 기타함수
class Teacher : public Man {
};
//main함수에서 학생객체와, 교수객체를 만들어 테스트해보시오.
int main()
{
Student kks("김컴소", 20, "C반", "202012000");
// Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
kks.s_show();
// hsh.t_show();
return 0;
}
//이름: 김컴소
//나이 : 20
//반 : C반
//학번 : 202012000
#include <iostream>
using std::cout;
using std::endl;
using std::string;
//사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
class Man {
protected: //상속할거라서 protected
string name;
int age;
public:
Man(string n, int a) { //멤버변수를 초기화하는 생성자를 구현하시오.
name = n;
age = a;
}
void m_show() { //기타 함수를 구현하시오. -> show()
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
};
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오. (멤버변수:반, 학번), 생성자, 기타함수
class Student : public Man {
private:
string ban;
string hak;
public:
Student(string n, int a, string b, string h) : Man(n,a) {
ban = b;
hak = h;
}
void s_show() {
m_show();
cout << "반 : " << ban << endl;
cout << "학번 : " << hak << endl;
}
};
//사람클래스로부터 상속받은 교수(Teacher)클래스를 만드시오. (멤버변수:전공, 담당과목), 생성자, 기타함수
class Teacher : public Man {
private:
string major; // 전공
string sub; // 담당 과목
public:
// 생성자에서 Teacher로 이름을 변경
Teacher(string n, int a, string m, string s) : Man(n, a) {
major = m;
sub = s;
}
void t_show() {
m_show();
cout << "전공 : " << major << endl;
cout << "과목 : " << sub << endl;
}
};
//main함수에서 학생객체와, 교수객체를 만들어 테스트해보시오.
int main()
{
Student kks("김컴소", 20, "C반", "202012000");
Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
kks.s_show();
hsh.t_show();
return 0;
}
//이름: 김컴소
//나이 : 20
//반 : C반
//학번 : 202012000
'C++' 카테고리의 다른 글
13. 바인딩, 오버로딩/오버라이 가상함수 (0) | 2024.11.26 |
---|---|
11. 함수 중첩, 디폴트 인자 (0) | 2024.11.12 |
8. const 동적 메모리 할당 (new, delete) (8) | 2024.11.05 |
7. 객체와 멤버, 생성자/소멸자, this 포인터 (0) | 2024.10.29 |
6. 접근 속성 클래스와 객체 만들기 (2) | 2024.10.15 |