Class

headkio·2020년 9월 9일
0

C++

목록 보기
6/35
post-thumbnail

클래스

선언

// Vector.h
class Vector
{
	int mX; // 미선언시 기본 private 권한
	int mY; // C++는 자동 초기화 X. Java는 0으로 초기화 해줌.

	friend class OtherClass; // OtherClass가 Vector Class의 Private에 접근 가능.

	public:
		Vector(); // 생성자 (선언안하면 기본 생성자를 컴파일러가 생성)
		Vector(int x, int y); // 오버로딩 생성자
		Vector(const Vector& clone); // 복사 생성자
		~Vector(); // 소멸자

		void SetX(int x);
		void SetY(int y);
		int GetX() const; // const : GetX 내부에서 무엇도 바꿀수 없다
		int GetY() const;
		void Add(const Vector& vector); // const : clone 변수는 바꿀수 없다.

	protected:
		int mProtected;

	private:
		int mPrivate1;
		int mPrivate1;
		int* mChars;
}
// Vector.cpp
Vector::Vector()
	: mX(0)
	, mY(0)
{
}

Vector::Vector(int x, int y)
	: mX(x)
	, mY(y)
{
	mChars = new char[TEMP_LENGTH];
}

Vector::~Vector()
{
	delete[] mChars; // 클래스 안 동적 생성 메모리가 있다면 해제
}

Vector::Vector(const Vector& other)
	: mX(other.mX)
	, mY(other.mY)
{
	// 깊은 복사 구현부
	mChars = new char[TEMP_LENGTH];
	memcpy(mChars, other.mChars, mChars*sizeof(char)*TEMP_LENGTH);
}

int Vector::GetX() const
{
	return mX;
}

void Vector::SetX(int x)
{
	mX = x;
}

void Vector::Add(const Vector& vector) 
{
	mX += vector.mX;
	mY += vector.mY; 
}

객체 생성/해제

Vector a; // Stack에 생성 (빠름) (Java에서는 불가능)

Vector* b = new Vector // Heap에 생성 (느림)
delete b; // 메모리 해제 필수!!!
b = NULL // 가비지값을 없애기 위해 하기도 한다. 필수는 아님.

Vector* list = new Vector[10]; // C++은 온전한 Vector 10개를 생성해 할당. Java는 주소만 생성.
delete[] list; // [] 반드시 넣을 것 !!!
list = NULL; // 필수 X

스택

new/delete VS malloc()/free()

  • new, delete는 기본 연산자, 생성자와 소멸자를 호출한다
  • malloc, free는 만들어진 메소드

struct vs class

  • C++에서는 차이가 없다.

  • 코딩 표준을 잘 정할 것.

    1. class는 oop로 사용

    2. struct는 원시 데이터를 위해 사용

      = memcpy() 가능한 것

연산자 오버로딩

+연산자

// Vector.h
class Vector
{
	public:
		Vector operator+(const Vector& rhs) const;
}
// Vector.cpp
Vector Vector::operator+(const Vector& rhs) const
{
	Vector sum;
	sum.mX = mX + rhs.mX;
	sum.mY = mY + rhs.mY;

	return sum;
}
// main.cpp
Vector sum = v1 + v2;

<< 연산자

std::ostream& operator<<(std::ostream& os, const Vector& rhs)
{
	os << rhs.mX << ", " << rhs.mY;
	return os
}
  • 남용하지 말자. (코드를 봐야 무슨 연산인지 알 수 있는 경우)

    → 그냥 따로 함수를 만들자

기본 생성자 "지우는" 법

header에만 선언하고 cpp를 구현하지 않는다.

class Vector
{
	public:

	private:
		Vector() {};
}

상속

// Animal.h
class Animal
{
}

// Cat.h
class Cat : public Animal
{
}
// Cat.cpp
Cat::Cat(int age, const char* name)
	: Animal(age)
{
	// 부모 객체 변수는 신경 쓰지 않고 내꺼만 세팅하면 된다.
}
  • 상속 받은 멤버 함수는 메모리에 한번만 쓰인다
    상속받은 클래스들은 같은 메모리의 함수를 쓴다.
    사실상 전역 변수와 같다.

오버라이딩 (다형성)

부모의 함수를 재정의 하여 자식이 사용.

껍데기는 같고 내용을 바꿔쓴다.

정적바인딩

Cat* myCat = new Cat();
Animal* myAnimal = new Cat();
// 앞에 있는 클래스로 생성된다.

동적바인딩

Class Animal
{
	public:
		virtual Animal(); // 가상 생성자
		virtual ~Animal(); // 가상 소멸자
}

Cat* myCat = new Cat();
Animal* myAnimal = new Cat();
// 뒤에 있는 클래스로 생성된다.
  • 가상 함수
    • 이건 실체 아님
    • 자식이 바꿔 쓸 예정이라 선언
    • 런타임에 어떤함수를 호출할지 결정한다.
    • 정적 바인드보다 느림
    • 가상 테이블이 생성됨
      • 가상 멤버함수 주소 테이블
      • 객체가 아닌 클래스당 1개의 테이블 보유

다중 상속

class TA : public Student, public Faculty
{
};

// Main.cpp
TA* myTA = new TA();
  • 생성자 호출 순서 = 상속 선언한 순서
    1. Student() → Faculty()
    2. 초기화 리스트의 순서와 상관 없다.
  • 최대한 쓰지 말자.

추상 클래스

class Animal
{
	public :
		virtual void Speak() = 0; // 순수 가상함수
	private :
		int mAge;
}
  • 하위 클래스에서 순수 가상함수를 구현하지 않으면 컴파일 에러
  • 순수 가상함수를 가진 베이스 클래스를 추상 클래스라 함

인터페이스

→ 함수만 있는 추상 클래스

→ C++ 자체적으로 인터페이스를 지원하지 않음

→ Java 흉내

class IFlyable 
{
	public:
		virtual void Fly() = 0;
}

class IWalkable // 앞에 "I" 를 붙인다.
{
	public:
		virtual void Walk() = 0;
}

class Bat : public IFlyable , public IWalkable 
{
	public:
		void Fly();
		void Walk();
}
profile
돌아서서 잊지말고, 잘 적어 놓자

0개의 댓글