본문 바로가기

C++ 프로그래밍 (1학년 2학기)

231123 C++ 프로그래밍 12주차

1. aa라는 객체의 인스턴스가 접근할 때에는 public에 있는 함수들만 접근할 수 있다.

2. 14열에 있는 class B : public A { }; 는 class B가 A의 public부분을 상속받아 다 이용할 수 있다는 것이다.

#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.
	return 0;
}

3. ?

 

4. 상속을 하게 되면 하나부터 열까지 만드는 것이 아니고 부모 클래스로부터 상속받아 개별 속성을 추가한다.

5. C++에서 부모클래스(superclass) - 자식클래스(subclass)의 표준 이름 : 기본(Base)클래스[B] - 파생(Derived)[A] 클래스

A is a subclass of B   |   B is a superclass of A

6.

class Dog : public Animal //C++

class Dog : Animal //C#, swift, kotlin

class Dog extends Animal //java, php

class Dog(Animal) //python

7. 부모 클래스의 private 속성은 상속이 불가능하고, protected와 public 속성은 상속이 가능하다.

8. 

#include <iostream> 

using std::cout; 
using std::endl; 

class A // 기본 클래스 A를 선언
{
	int x; // private 변수 x 선언

public: // 이후 선언되는 멤버들은 public으로 선언
	void setX(int i) {	x = i;	} 
    // 멤버 함수 setX, x 값을 설정하는 함수
	void showX() { cout << x << endl; } 
    // 멤버 함수 showX, x 값을 콘솔에 출력하는 함수
};

class B :public	A // 기본 클래스 A를 상속받는 파생 클래스 B 선언
{
	// 아무 것도 없어요. 그러나 A 클래스의 public 멤버는 상속받았습니다.
};

int main() { // 메인 함수 선언
	A aa; // A 클래스의 객체 aa 생성
	aa.setX(1); // aa의 x 값을 1로 설정
	aa.showX(); // aa의 x 값을 출력

	B bb; // B 클래스의 객체 bb 생성

	bb.setX(10); // bb의 x 값을 10으로 설정
	bb.showX(); // bb의 x 값을 출력
	return 0; // 메인 함수 종료
}

9. 

#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.x = 1; // 오류 ① bb.setX(1);
	bb.y = 2; // 오류 ② bb.setY(2);
	bb.showX(); // 기본클래스의 멤버접근
	bb.showY(); // 파생클래스의 멤버접근
	return 0;
}

10. 

#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() { showX(); cout << y << endl; } 
	//안에 cout<<x<<y<<endl;를 넣으면 오류가 발생함
};
int main()
{
	B bb;
	bb.setX(1); // 기본클래스의 멤버접근
	bb.setY(2); // 파생클래스의 멤버접근
	bb.showX(); // 기본클래스의 멤버접근
	bb.showXY(); // 파생클래스의 멤버접근
	return 0;
}

11. private 상속 접근한 경우(class Dog : private Animal) 기본 클래스의 모든 멤버가 파생 클래스의 private 멤버가 된다.

12. 

#include <iostream>
using std::cout;
using std::endl;
class A
{
	int x = 1;
	// In-class member initializers 클래스 내에서 멤버를 initialize하는 것
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

13.

#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 :private A //비공개적으로 상속받는다
{
	int y;
public:
	void setXY(int i, int j) { setX(i); y = j; }
	// 기본 클래스의 public 멤버 접근
	void showXY() { showX(); cout << y << endl; }
};
int main()
{
	B bb;
	bb.setXY(1, 2); // 파생클래스의 멤버접근
	bb.showXY(); // 파생클래스의 멤버접근
	return 0;
}

14. protected 속성은 상속이 가능하긴 하지만 자식의 protected로 오고, 자식 클래스에 protected가 없다면 private부분으로 상속됨

 

15. private 속성과 protected 속성의 공통점과 차이점

공통점 : 외부에서 접근이 불가능하다.

차이점 : private는 상속이 불가능하지만 protected는 상속이 가능하다.

16.

#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;
}

17. 부모클래스에서 클래스를 생성할 때, 클래스 외부에서는 접근하지 못하게 하고 자식클래스에서는 마음대로 접근할 수 있게 하려면 멤버의 속성을 protected로 사용해야 한다. 또한 자식 클래스에서 상속은 public으로 해야 private를 제외한 protected와 public 모두를 상속받을 수 있다.

18. 기본 클래스 생성자는 파생 클래스 생성자보다 먼저 실행되고, 소멸자는 역순으로 실행된다.

#include <iostream>
using std::cout;

class A // 기본 클래스 A를 선언
{
public: // 이후 선언되는 멤버들은 public으로 선언
	A(){cout<<"A의 생성자\n";} 
    // A 클래스의 생성자, 객체 생성 시 "A의 생성자" 출력
	~A(){cout<<"A의 소멸자\n";} 
    // A 클래스의 소멸자, 객체 소멸 시 "A의 소멸자" 출력
};

class B:public A // 기본 클래스 A를 상속받는 파생 클래스 B 선언
{
public: // 이후 선언되는 멤버들은 public으로 선언
	B(){cout<<"B의 생성자\n";} 
    // B 클래스의 생성자, 객체 생성 시 "B의 생성자" 출력
	~B(){cout<<"B의 소멸자\n";} 
    // B 클래스의 소멸자, 객체 소멸 시 "B의 소멸자" 출력
};

int main() // 메인 함수 선언
{
	B ob; // B 클래스의 객체 ob 생성. 
	return 0; // 메인 함수 종료. 이 때 B의 소멸자와 A의 소멸자가 순서대로 호출됨
}

19. 파생 클래스(부모) 생성자에서 기본 클래스(자식) 생성자에 매개변수전달 형식

  • 파생클래스생성자(매개변수 리스트) :기본클래스생성자(매개변수리스트) { : }
  • 파생 클래스의 생성자가 호출될 때 기본 클래스의 생성자를 먼저 호출하도록 하기 위한 구문
  • "B 객체를 생성할 때는 A의 생성자를 i를 매개변수로 하여 먼저 호출하라"는 의미
#include <iostream> // 입출력 관련 헤더 파일을 포함시키는 전처리기 

using std::cout; // std 네임스페이스 안의 cout 객체를 직접 사용하기 위한 선언
using std::endl; // std 네임스페이스 안의 endl 객체를 직접 사용하기 위한 선언

class A { // 기본 클래스 A를 선언
	int a; // private 변수 a 선언
public: // 이후 선언되는 멤버들은 public으로 선언
	A(int i) { // A 클래스의 생성자, 객체 생성 시 "A의 생성자" 출력하고 a를 i로 설정
		cout << "A의 생성자\n";
		a = i;
	}
	~A() { cout << "A의 소멸자\n"; } // A 클래스의 소멸자, 객체 소멸 시 "A의 소멸자" 출력
	void showA() { cout << a << '\n'; } // 멤버 함수 showA, a 값을 콘솔에 출력하는 함수
};

class B :public A { // 기본 클래스 A를 상속받는 파생 클래스 B 선언
	int b; // private 변수 b 선언
public: // 이후 선언되는 멤버들은 public으로 선언
	B(int i, int j) :A(i) { 
    // B 클래스의 생성자, 객체 생성 시 "B의 생성자" 출력하고 b를 j로 설정. 
    // i는 기본 클래스 생성자의 매개변수로 전달
		cout << "B의 생성자\n";
		b = j;
	}
	~B() { cout << "B의 소멸자\n"; } // B 클래스의 소멸자, 객체 소멸 시 "B의 소멸자" 출력
	void showB() { cout << b << endl; } // 멤버 함수 showB, b 값을 콘솔에 출력하는 함수
};

int main() // 메인 함수 선언
{
	B bb(10, 20); // B 클래스의 객체 bb 생성. 10은 A의 생성자로, 20은 B의 생성자로 전달됨
	bb.showA(); // bb의 a 값 출력
	bb.showB(); // bb의 b 값 출력
	return 0; // 메인 함수 종료
}

20. 계층적 다중상속에서 계층적 매개변수전달

#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;
}

참고 자료 : 한성현 교수님 수업자료

댓글