반응형

한국인을 위한 코드 미리보기

#include <iostream>

class MyClass
{

	int num = 0;

public:

	int Get() { return num; }
	void Set(int a) { num = a; }

	MyClass Sum1(MyClass obj)
	{
		MyClass temp;
		temp.Set(obj.Get() + this->Get());
		return temp;
	}
	friend MyClass Sum2(MyClass obj1, MyClass obj2);
};

MyClass Sum2(MyClass obj1, MyClass obj2)
{
	MyClass temp;
    // MyClass에서 friend 키워드를 주었기 때문에 private멤버에 접근이 가능한ww
	temp.num = obj1.num + obj2.num;
	return temp;
}

int main()
{

	MyClass x; x.Set(1);
	MyClass y; y.Set(2);

	MyClass z1 = x.Sum1(y);
	MyClass z2 = Sum2(x, y);

	std::cout << z1.Get() << " " << z2.Get();

	return 0;

}

 

미친 나도 친구가 없는데 class가 친구가 있네

 

friend 키워드를 통해 해당 함수에 자기의 private 멤버에 접근할 수 있다.

뭐야 ㅅㅂ 미친거아님?wwww 이라고 생각할 수도 있겠지만.... class의 캡슐화에 위배된다...라네요.

사실 저는 캡슐화 알빠노(물론 중요함. 하기 귀찮아서 그렇지) 라는 입장이기 때문에 별 생각 안들지만, 딱 보자마자 든 생각이.. 의존성이 너무 강해진다? 였다는 것.

(의존성이라는 것은 서로가 서로를 너무 의존해서 하나가 바뀌거나 없어지면 의존하던 코드도 같이 무너지는? 그런 느낌이라고 생각합니다. 사실 제 생각임 팩트인진 모름.)

 

어쨋든 friend 써보니까 매우 신세계긴 하네요. 하지만 안쓸듯. 일단 앞서 말했듯이 캡슐화를 위배하는 것도 있지만, 저는 그런거 알빠노고, 사실 의존성이 강해지는게 너무 맘에 걸리긴 한다는ww 추가적으로 friend를 남발하다 보면 여기저기서 멤버를 가져오기 때문에 그 유명한 스파게티코드가 될거 같다는? 느낌적인 느낌

 

그래도 연관성이 높은 객체끼리 쓰면 편의성이 아주 높아진다고 하니 감당가능하신 분들은 알아서 쓰시길.... 전 지능딸려서 남발하다가 나중에 유지보수를 못할 것 같아서 안쓸 것 같습니다 ㅅ_ㄱ...

 


20240907추가

friend..... 쓰는 날이 오긴 하더라.......

캡슐화를 위반하는 대신 은닉성을 좀 더 강화할 수 있어서 가끔 쓸거같습니다....

다만 남발하면 여전히 복잡해지고, 어쨋든 캡슐화를 위반하는거니 조심해서 써야 된다는 강박을 가지고 있는 중..

friend가 좋긴한데 너무 치트키 느낌이라 공부하는 입장에선 자제해서 써야겠습니다.

반응형
반응형

오늘 수업 들은것.... 근데 뭔가 글쓰기는 귀찮아서 주석으로 대체한다. (주석적다가 일부분 수업 놓침 망함티비)

#include <iostream>

class ConstTest
{
public:

	const int a = 0;
	int b = 0;

	ConstTest() {}
	~ConstTest() {}
	void Addnum()
	{
		b++;
	}
	int GetNum() const
	{
		return b;
	}
	void Show() const
	{
		std::cout << a << " " << b << '\n';
	}
};

int main()
{
	const ConstTest* a = new ConstTest(); // const객체 선언. 객체의 멤버를 바꾸지 않겠다!
	ConstTest* const b = new ConstTest(); // non-const객체 선언. 객체의 멤버를 바꿀 수 있다. but b포인터의 주소는 바꿀 수 없다.

	a->b += 1; // 에러. const객체는 멤버를 변경할 수 없다.
	b->b += 1; // 가능.

	a->Addnum(); // 에러. const객체는 const함수만 호출 가능.
	b->Addnum(); // 가능.

	a->GetNum() = 1; // const함수기 때문에 반환 값을 바꿀 수 없다.
	b->GetNum() = 1; // 위와 동일

	a->Show(); // 가능. const객체는 const함수는 호출할 수 있기 때문.
	b->Show(); // 가능.

	a = b; // 가능. 주소는 바꿀 수 있다. 멤버만 못바꿈.
	b = a; // 불가능. 포인터를 const화 시켰기 때문에 주소를 바꿀 수 없다.

	delete a;
	delete b;

	a = new ConstTest(); // 가능
	b = new ConstTest(); // 에러. const변수는 선언과 동시에 초기화 되어야 하기 때문

}

 

알아서들 이해하셨길....

반응형
반응형

하 개 오랜만에 글쓴다....

 

한국인을 위한 코드 미리보기

#include <iostream>

class Object
{
private:
	static int m_obejctCount;
	const char* m_name;
public:
	Object(const char* _name)
	{
		++m_obejctCount;
		m_name = _name;
		std::cout << "CreateObject (" << m_name << ")\n";
	}
	~Object()
	{
		--m_obejctCount;
		std::cout << "DeleteObject (" << m_name << ")\n";
	}
	static int GetObjectCount()
	{
		return m_obejctCount;
	}
	static void DestroyObject(Object* _target)
	{
		delete _target;
	}
};
int Object::m_obejctCount = 0;

int main()
{
	Object* a = new Object("Object1");
	Object* b = new Object("Object2");
	Object* c = new Object("Object3");

	Object::DestroyObject(c);

	std::cout << "Object Count : " << Object::GetObjectCount() << "\n";
}


먼저 알아가야 할 것..

밑줄  << 이렇게 밑줄 쫙 그어놓은건 ㅈㄴ 중요한거고

배경  << 이렇게 배경해놓은거는 그냥 한번 봤으면 좋겠다는 정도고

밑줄배경 << 이건 그냥 개 ㅈㄴ게 ㅁㅊ 레전드로 중요한거다 다른거 안봐도 이건 봐줍메 제발

class내에서 변수에 static을 붙였다 = 정적멤버변수

class내에서 함수에 static을 붙였다 = 정적멤버함수

(이게 ㅈㄴ게 중요!!!!!!) static은 전역변수, 함수 취급을 받는다. 하지만 class 내부에 멤버로 주게 될 경우 그냥 그 class 내부에서만 쓸 수 있게 한정해줄 뿐이다. 너무 어렵게 생각하지 말자... 첨에 이 개념을 못가져가서 많이 헷갈렸다.


static은 프로그램 시작시 할당되는데, 문제는 class객체의 생성 전에 할당된다는 것이다....

때문에 정적멤버변수는 class안에서 초기화를 못한다...(class 내부에서 해보고싶으면 해보자... 내 기억엔 에러뜸...)

따라서 정적멤버변수는 전역범위에서 따로 초기화를 해줘야 한다!!

이렇게...

 

그리고 위와 같은 이유로 멤버함수도 당연히 this포인터를 받지 못한다...

따라서 this->m_name과 같이 정적멤버함수는 비정적멤버변수에 접근하지 못한다.

근데 ㅈㄴ 웃긴게... 위에 사진처럼 정적멤버함수에 매개변수로 자신의 class를 자료형으로 줄 수 있음... 심지어 위에 사진에 있는 _target의 비정적멤버변수도 사용 가능. (이 순간 "아니 ㅅㅂ!! this는 못쓰는데 이건 어캐 씀?" 라는 의문을 가짐)

당연히 static은 프로그램 시작 시 할당되는데.... class의 존재여부를 모르는게 당연한거 아닌가? 해서 교수님한테 물어봄ㅋㅋ

교수님왈, 매개변수를 받아 쓰는건 초기화 이후의 과정이므로... 상관없다... 라는 느낌으로 말하셨는데 느낌만 알겠고 설명을 못하겠다...

 

자 여기까지 static의 멤버변수와 멤버함수에 대한 설명을 다 했다!  라고 하고싶은데 중요한게 하나 더 남아있음..ㅇㅇ

위에서 설명했지만 class내의 static도 전역변수,함수라고 생각하라고 했는데, 말 그대로 객체가 여러 개여도 정적 멤버는 하나밖에 존재할 수 없다.

따라서 위 사진에 a, b, c객체가 m_objectCount의 값을 공유한다는 것이다.

더 쉽게 말하면 그냥 m_objectCount라는 전역변수가 있는데, Object라는 class 내에서만 쓸 수 있는 것 뿐이다. 때문에 출력해보면 정적멤버변수인 ObjectCount가 생성(+1)-생성(+1)-생성(+1)-삭제(-1) = 2가 나오는 것이다!

 

하 적다보니 귀찮아서 그냥 대충 설명하게 된다... 알아서 잘 이해하셨길...

반응형
반응형

미리 컴파일된 헤더(Precompiled Header)란 여러 헤더들을 한 헤더에 묶고, 그 헤더를 미리 컴파일 하여 컴파일 시간을 줄여줄 수 있다. 

 

프로젝트 우클릭 - 속성 - C/C++ - 미리 컴파일된 헤더

 

운영체제 확인은 필수

 

 

사용 클릭

 

파일 이름 설정 (아무거나 입력해도 상관없다!!)

 

설정한 이름의 헤더랑 같은 이름의 헤더를 만든다...

 

헤더에 미리 컴파일 할 헤더를 넣어준다!!

 

이제 사용 할 CPP파일에 설정한 헤더(이 글에선 stdafx)를 #include해주면 그 안에 있는 헤더를 다 사용 할 수있다!!!

 

주의할 점은 미리 컴파일된 헤더에 컴파일한 헤더를 자주 바꿀 경우 오히려 컴파일이 느려진다는 것이다. (마소피셜 두배정도느려진다 하네요)

반응형

+ Recent posts