템플릿
1. const와 주솟값 관련된 문제
bool Push( const T &pushValue)
{ // &T 자료형에 대한 const
if (!isFull())
{
stackPtr[++top] = pushValue
return true;
}
cout << "The Stack is FUll!" << endl;
return false;
}
왜 매개변수를 저따구로 썼을까?
1. const
2. pushValue의 주솟값
2. Pop함수에서 pop 구현 코드에 관련된 문제
bool Push( const T &pushValue)
{ // T 자료형에 대한 const
if (!isFull())
{
stackPtr[++top] = pushValue;
return true;
}
return false;
}
bool Pop(const T &popValue)
{
if (!isEmpty())
{
popValue = stackPtr[top--];
return true;
}
return false;
}
top의 값을 현 스택의 top에서 한단계 밑으로 설정해주는건데 왜 popValue에 stackPtr[top--]값을 대입하는거죠?
단순히 popValue를 설정해주고 top의 값을 한단계씩 내려주는 것만을 pop을 수행했다고 하시는건가?
stackPtr 메모리 자체에 있는 값을 삭제하는 코드는 없는건가?
그리고 Push함수와 Pop함수에서 ++top, top--을 사용한 후위연산자와 전위 연산자의 차이가 있는지 궁금함
그리고 헤더파일과 구현파일을 분리할 때
template <typename T>
bool Stack<T>::Push(const T& pushValue)
{ // T 자료형에 대한 const
if (!isFull())
{
stackPtr[++top] = pushValue;
return true;
}
return false;
}
이렇게 해야 됨 알고 있는 것 같지만 bool, Stack, <T>, :: 키워드들을 어디에 어떤 순서로 써야하는지 까먹을 수 있음
class Point {
public:
int x;
int ReturnValue();
};
int Point::ReturnValue() {
return x;
}
참고 : 템플릿 함수 쓰지 않았을 때 헤더 구현파일 분리 방법 -> (함수 리턴 값 자료형) (클래스) :: 함수명
3. 함수 템플릿과 클래스 템플릿의 차이점
위 예제에서 쓰인 템플릿은 클래스의 멤버변수가 아닌 popValue와 pushValue의 자료형을 매개변수화했으므로 함수 템플릿이라고 할 수 있는가?
--> Maybe Yes?
생성자 소멸자 매개변수 문제 해결
1. 생성자의 매개변수에 문자열을 넣었을 때 char * 자료형을 가지고 있는 멤버 변수의 값 초기화 시키기
+ strcpy 관련 에러 해결
소스코드이다.
#pragma once
#ifndef CREATE_H
#define CREATE_H
class CreateAndDestroy {
public:
CreateAndDestroy(int, char *); // 생성자
~CreateAndDestroy(); // 소멸자
private:
int objectID;
char* message;
};
#endif CREATE_H
Create.h
#include <iostream>
#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS
#include "create.h"
using namespace std;
CreateAndDestroy::CreateAndDestroy(int objectNumber, char * messagePtr) // 생성자
{
objectID = objectNumber;
strcpy(message, messagePtr);
cout << "Number : " << objectID << " 생성자 실행" << message << endl;
}
CreateAndDestroy::~CreateAndDestroy() //소멸자
{
cout << (objectID == 1 || objectID == 6 ? "n" : "");
cout << "Number : " << objectID << " 소멸자 실행" << message << endl;
}
CreateAndDestroy.cpp
#include <iostream>
using namespace std;
#include "create.h"
void create(void);
CreateAndDestroy first(1, "(메인 함수 전 전역)");
int main()
{
cout << "n 메인 함수 : 처음 시작 " << endl;
CreateAndDestroy second(2, "(메인함수 안의 automatic)");
static CreateAndDestroy third(3, "(메인 함수 안의 static)");
create(); // what is this?
cout << "n 메인 함수 : 다시 시작!" << endl;
CreateAndDestroy fourth(4, "( 메인 함수 안의 automatic)");
cout << "n 메인 함수 : 실행 종료 " << endl;
return 0;
}
void create()
{
cout << "\n Create함수 : 함수 시작 " << endl;
CreateAndDestroy fifth(5, "(create 함수 안의 automatic)");
static CreateAndDestroy sixth(6, " (create 함수 안의 static )");
CreateAndDestroy seventh(7, "(create 함수 안의 automatic)");
cout << "\n Create 함수 : 실행 종료 " << endl;
}
객체의 생성자와 소멸자가 어떤 순서로 이루어지는 지 알 겨를 도 없이
컴파일이 되지 않았다.
흠
아마 입력된 문자열들은 전부 const char 배열 형태인데 매개변수의 자료형은 char pointer이기 때문이 아닐까?
사실 이번 수업이 아니고라도 앞서서 열혈 C++ 공부할 때 많이 부딪혔던 에러이다. 미루고 미루다 시험기간에 이러고 있네..
문자열은 문자열이 시작되는 주소를 가리키게 된다. 즉 포인터인데,
char *ptr = "hello"와 같이 선언하면 포인터 ptr은 "hello"라는 문자열을 가리키는 포인터가 되는 것이다.
연산자 오버로딩
전역 함수로서 연산자 함수 중 << , >> 연산자 내용 이해하기
ostream & 형의 왼쪽 피연산자
ex) cout << classObject 에서 cout이 객체인데 왜 전역함수로 생각하는지?
해결 : PhoneNumber 객체를 출력하는 << 연산자를 오버로딩한다고 가정하자
PhoneNumber number;
cout << number << endl; 과 같이 구현하는데
이를 멤버 함수로 구현하면 객체 cout의 클래스인 ostream의 멤버함수를 수정해야 한다.
C++의 standard library를 수정할 수 없으므로 전역함수를 사용하고, friend 키워드를 통해 PhoneNumber 클래스의 private한 멤버 변수를 사용할 수 있도록 한다.
++연산자 오버로딩 과정에서 dummy parameter 넣는 이유
다형성
정적 바인딩 : 특정 객체가 dot 연산자로 멤버 함수를 호출하면 virtual 여부와 관계없이 (다형성 구현 여부와 상관 없이, 그 객체가 기본클래스의 함수를 호출하거나 파생 클래스의 함수를 호출하는 것과 상관없이 ) 컴파일 시간에 함수가 호출된다. 따라서 정적 바인딩이다.
UML 다이어그램
상속 관계에서 UML 다이어그램 표현하기
포인터 변수, 레퍼런스 변수, const, static 등 다양한 형태의 변수에 대한 표현 방법
상속
check point
1) public, private, protected 상속?
2) 기본 클래스의 멤버와 파생 클래스의 멤버가 동일할 때 (파생 클래스의 객체).area를 쓰면 파생 클래스의 멤버가 호출됨. -> 기본 클래스의 멤버를 사용하기 위해서 Shape::area 와 같이 사용하면 된다
3) 파생 클래스의 생성자를 정의할 때 Member Initializer에서 기본 클래스의 생성자를 호출해 반드시 초기화해주어야 한다는 것!
4) 파생 클래스가 기본 클래스의 데이터 멤버에 접근하기 위해서는?
① 기본 클래스의 데이터 멤버를 protected로 사용하기 -> 파생 클래스에 모두 상속되며(private도 상속은 되나, 접근할 수 없다) 파생 클래스의 멤버 함수에서 사용할 수 있다.
- 장점 : 파생 클래스가 기본 클래스의 데이터 멤버를 직접 사용해서, set/get 호출에 필요한 처리 시간을 절약할 수 있다.
- 단점 : 유효성 검사가 불가능하다. 파생 클래스의 구현이 기본 클래스의 구현에 더 의존적이게 되고, 기본 클래스 수정 시 파생 클래스 또한 조절되어야 한다.
② get함수를 사용하여 기본클래스의 데이터 멤버에 접근하기
기본 클래스에서 virtual 멤버함수를 사용해 함수를 오버라이드 하였다.
이때 기본 클래스의 멤버함수는 재정의 된, override된 멤버 함수? 아니면 override한 멤버 함수?
override란, virtual의 유무와 상관없이 함수를 재정의한 것 자체를 의미한다.
재정의하는 함수에서 기본 클래스의 함수를 호출할 때, CommissionEmployee::earnings()와 같이 호출 안하고 earnings()이렇게 호출하면 파생 클래스의 함수가 호출되므로 무한루프이다.
생성자와 소멸자는 상속되지 않는다.
생성자 소멸자 호출의 다양한 케이스
#include <iostream>
using namespace std;
class A{
public:
A() {
cout << "A 생성자" << endl;
}
~A() {
cout << "A 소멸자" << endl;
}
};
class B : public A
{
public:
B() : A()
{
cout << "B 생성자" << endl;
}
~B() {
cout << "B 소멸자" << endl;
}
};
class C : public A
{
public:
C()
: A()
{
cout << "C 생성자" << endl;
}
~C() {
cout << "C 소멸자" << endl;
}
};
int main()
{
A a; // A 생성자
A* b = new B(); // A 생성자
//A* c = new C();
C c; // A 생성자 C 생성자
// B생성자
// A소멸자
delete b; // A소멸자
//C 소멸자
//A 소멸자
//A 소멸자
return 0;
}
#include <iostream>
using namespace std;
class A1{
public:
A1() {
cout << "A1 생성자" << endl;
}
~A1() {
cout << "A1 소멸자" << endl;
}
};
class B
{
private:
A1 a1; // 복합 관계의 클래스
public:
B()
{
cout << "B 생성자" << endl;
}
~B() {
cout << "B 소멸자" << endl;
}
};
class A2 {
public:
A2() {
cout << "A2 생성자" << endl;
}
~A2() {
cout << "A2 소멸자" << endl;
}
};
class C : public B
{
private :
A2 a2; // 복합관계
public:
C()
{
cout << "C 생성자" << endl;
}
~C() {
cout << "C 소멸자" << endl;
}
};
int main()
{
// C가 B를 상속하고, B에는 A1 객체가, C에는 A2객체가 복합관계에 있는 상황
C c;
// A1 생성자 -> B 생성자 -> A2 생성자 -> C 생성자 -> C 소멸자 -> A2 소멸자 -> B 소멸자 -> A1 소멸자
// 원래대로 B 생 -> C 생 -> C 소 -> B 소 이렇게 되는데, B와 C 생성자가 호출되기 앞서 복합 관계에 있는 A1과 A2가 각각 먼저 생성되는 것이고, 소멸자도 원래대로 C -> B 이렇게 소멸되는 건데 소멸자가 호출되면 그 클래스의 복합관계에 있는 게 연쇄적으로 소멸되어 저렇게 만들어지는 것이다.
return 0;
}
'Major Study > Object Oriented Programming' 카테고리의 다른 글
연산자 오버로딩 / 상속 / 다형성 구현 프로젝트 해결 과정 (0) | 2021.10.08 |
---|---|
C++ template 내용 정리(열혈 C++, 강의노트, 기타 자료 참고) (0) | 2021.06.15 |
객체지향 프로그래밍2 기말고사 대비 문제 wirte-up (0) | 2021.06.14 |
객체지향 프로그래밍 프로젝트 (상속과 다형성, 가상함수) 해결 과정 / 가상 함수, 다형성 개념 정리 (0) | 2021.05.31 |
2021 객체지향 프로그래밍 중간고사 대비 (0) | 2021.04.17 |