티스토리 뷰

반응형

const 객체와 const 객체의 특성들

 

const int num =10;

const SoSimple sim(20);

 

이 객체의 데이터 변경을 허용하지 않겠다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;


class SoSimple 
{
private:
	int num;
public:
	SoSimple(int n) :num(n)
	{}
	SoSimple& AddNum(int n)
	{
		num += n;
		return *this;
	}
	void ShowData() const
	{
		cout << "num: " << num << endl;
	}
};

int main(void)
{
	const SoSimple obj(7);
	obj.ShowData();
	return 0;
}

 

const 객체에서는 const가 붙은 것만 호출을 할 수 있다!

 

const 함수와 오버로딩

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;


class SoSimple 
{
private:
	int num;
public:
	SoSimple(int n) :num(n)
	{}
	SoSimple& AddNum(int n)
	{
		num += n;
		return *this;
	}
	void ShowData() const
	{
		cout << "num: " << num << endl;
	}
	void SimpleFunc()
	{
		cout << "SimpleFunc: " << num << endl;
	}
	void SImpleFunc() const
	{
		cout << "const Simple Func: " << num << endl;
	}
};

void YourFnc(const SoSimple& obj)
{
	obj.SImpleFunc();
}

int main(void)
{
	SoSimple obj1(2);
	const SoSimple obj2(7);

	obj1.SImpleFunc();
	obj2.SImpleFunc();

	YourFnc(obj1);
	YourFnc(obj2);
	return 0;

}

 

오버로딩하면 const는 const 심플을 반환하고, 일반은 일반을 반환환다.

 

 

06-2 클래스와 함수에 대한 friend 선언

A클래스가 B클래스를 대상으로 friend 선언을 하면, B클래스는 A클래스의 private 멤버에 직접 접근이 가능하다.

단, A클래스도 B클래스의 private 멤버에 직접 전근이 가능 하려면, B클래스가 A클래스를 대상으로 friend 선언을 해야한다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;


class Girl;

class Boy
{
private:
	int height;
	friend class Girl;
public:
	Boy(int len):height(len)
	{}
	void ShowYourFriendInfo(Girl& frn);
};

class Girl
{
private:
	char phNum[20];
public:
	Girl(char* num)
	{
		strcpy(phNum, num);
	}
	void ShowYourFriendInfo(Boy& frn);
	friend class Boy;
};

void Boy::ShowYourFriendInfo(Gir& frn)
{
	cout << "Her Phone number: " << frn.phNum << endl;
}

void Girl::ShowYourFriendInfo(Boy& frn)
{
	cout << "His height: " < frn.height << endl;
}

int main(void)
{
	Boy boy(170);
	Girl girl('010-1234-5678');
	boy.ShowYourFriendInfo(girl);
	girl.ShowYourFriendInfo(boy);
	return 0;
}

 

friend 선언은 정보은닉을 해치기에 되도록이면 안 하는 게 좋다!

 

06-3 C++에서의 static

C언어에서 이야기한 static

전역변수에 선언된 static

-> 선언된 파일 내에서만 참조를 허용하겠다는 의미

함수 내에 선언된 static의 의미

->한번만 초기화되고, 지역변수와 달리 함수를 빠져나가도 소멸되지 않는다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;


void Counter()
{
	static int cnt;
	cnt++;
	cout << "Current cnt: " << cnt << endl;
}

int main(void)
{
	for (int i = 0; i < 10; i++)
	{
		Counter();
	}
	return 0;
}

 

원래라면 함수에서 반환값이 없기에 포인터를 통한 접근을 해야만 초기화되지않고 값의 증가가 이루어지지만, 값의 증가가 이루어지고 있다.

 

전역변수가 필요한 상황

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;


int simObjCnt = 0;
int cmxObjCnt = 0;

class SoSimple
{
public:
	SoSimple()
	{
		simObjCnt++;
		cout << simObjCnt << "번째 SoSimple 객체" << endl;
	}
};

class SoComplex
{
public:
	SoComplex()
	{
		cmxObjCnt++;
		cout << cmxObjCnt << "번째 SoComplex 객체" << endl;
	}
	SoComplex(SoComplex& copy)
	{
		cmxObjCnt++;
		cout << cmxObjCnt << "번째 SoComplex 객체" << endl;
	}
};

int main(void)
{
	SoSimple sim1;
	SoSimple sim2;

	SoComplex com1;
	SoComplex com2 = com1;
	SoComplex();
	return 0;
}

 

이 경우는 어디서든 객체에 접근이 가능하기에 문제를 일으킬 소지가 높다.

static을 쓰면 이 문제를 해결할 수 있다.

 

static 변수는 객체가 생성할 때마다 생성되는 것이 아니며, 하나만 생성되며 그 접근권한을 객체에서 받았을 뿐이다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;



class SoSimple
{
private:
	static int simObjCnt;
public:
	SoSimple()
	{
		simObjCnt++;
		cout << simObjCnt << "번째 SoSimple 객체" << endl;
	}
};
int SoSimple::simObjCnt = 0;

class SoComplex
{
private:
	static int cmxObjCnt;
public:
	SoComplex()
	{
		cmxObjCnt++;
		cout << cmxObjCnt << "번째 SoComplex 객체" << endl;
	}
	SoComplex(SoComplex& copy)
	{
		cmxObjCnt++;
		cout << cmxObjCnt << "번째 SoComplex 객체" << endl;
	}
};
int SoComplex::cmxObjCnt = 0;

int main(void)
{
	SoSimple sim1;
	SoSimple sim2;

	SoComplex com1;
	SoComplex com2 = com1;
	SoComplex();
	return 0;
}

 

int SoComplex::cmxObjCnt = 0; 

객체가 호출될 때마다 초기화가 되면 안 되기 때문에 외부에 초기화 선언을 넣는다.

 

static 함수의 또다른 접근 방법

cout<<SoSimple::simObjCnt;

cout<<sim1.simObjCnt;

cout<<sim2.SimObjCnt;

 

다 같은 출력결과를 갖지만, 첫번째가 분명히 어디에 접근하는지를 보여주기에 첫 번쨰처럼 쓰는 것이 좋다.

 

 

static 멤버함수

-선언된 클래스의 모든 객체가 공유한다.

-public으로 선언이 되면, 클래스의 이름을 이용해서 호출이 가능하다.

-객체의 멤버로 존재하는 것이 아니다.

 

 

const static 멤버

클래스 내에 선언된 const 멤버변수의 초기화는 이니셜라이저를 통해서만 가능했지만, const static은 선언과 동시에 초기화가 가능하다.

class Country

{

public:

 static int RUSSIA = 1707540;

};

 

키워드 mutable

-const 함수 내에서의 값의 변경을 예외적으로 허용한다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;



class SoSimple
{
private:
	int num1;
	mutable int num2;//const 함수에 대해 예외를 둔다
public:
	SoSimple(int n1, int n2)
		:num1(n1),num2(n2)
	{}
	void ShowSimpleData() const
	{
		cout << num1 << ", " << num2 << endl;
	}
	void CopyToNum2() const
	{
		num2 = num1;
	}
};

int main(void)
{
	SoSimple sm(1, 2);
	sm.ShowSimpleData();
	sm.CopyToNum2();
	sm.ShowSimpleData();
	return 0;
}

 

CopyToNum2에서 const 선언이 됐지만 대입이 완료됐다.

const의 의미를 잃게 할 수 있으므로 제한된 상황에서만 사용하자.

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함