const 함수 오버로딩
const의 유무에 따라 같은 이름의 함수도 구분될 수 있다.
#include<iostream>
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 YourFunc(const SoSimple& obj)
{
obj.SimpleFunc();
}
int main()
{
SoSimple obj1(2);
const SoSimple obj2(7);
obj1.SimpleFunc();
obj2.SimpleFunc();
YourFunc(obj1);
YourFunc(obj2);
return 0;
}
클래스와 함수에 대한 friend 선언
클래스 간의 friend를 선언하면 private 멤버를 볼 수 있는지 여부가 결정된다.
#include<iostream>
#include <string.h>
#pragma warning(disable:4996)
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];
friend class Boy;
public:
Girl(const char num[20])
{
strcpy(phNum, num);
}
void ShowYourFriendInfo(Boy& frn);
};
void Boy::ShowYourFriendInfo(Girl& frn)
{
cout << "Her phone number : " << frn.phNum << endl;
}//Girl클래스 정의 전에 매개변수에 Girl 객체가 있는 함수를 정의하면 에러가 뜬다.
void Girl::ShowYourFriendInfo(Boy& frn)
{
cout << "His height : " << frn.height << endl;
}
int main()
{
Boy boy(170);
Girl girl("010-1234-5678");
boy.ShowYourFriendInfo(girl);
girl.ShowYourFriendInfo(boy);
return 0;
}
이번에는 함수 대상의 friend선언을 알아보겠다.
//MyFriendFunction.cpp
#include <iostream>
using namespace std;
class Point;
class PointOP {
private:
int opcnt;
public:
PointOP()
:opcnt(0)
{}
Point PointAdd(const Point&, const Point&);
Point PointSub(const Point&, const Point&);
~PointOP(){
cout << "Operation times : " << opcnt << endl;
}
};
class Point {
private:
int x;
int y;
public:
Point(const int& xpos, const int& ypos)
: x(xpos), y(ypos) {}
friend Point PointOP::PointAdd(const Point&, const Point&);
friend Point PointOP::PointSub(const Point&, const Point&);
//PointOP의 멤버함수 PointAdd,PointSUb에 대해 friend 선언을 하고 있다.
friend void ShowPointPos(const Point&);
};
Point PointOP::PointAdd(const Point& pnt1, const Point& pnt2)
{
opcnt++;
return Point(pnt1.x + pnt2.x, pnt1.y + pnt2.y);
}
Point PointOP::PointSub(const Point& pnt1, const Point& pnt2)
{
opcnt++;
return Point(pnt1.x - pnt2.x, pnt1.y - pnt2.y);
}
void ShowPointPos(const Point& pos)
{
cout << pos.x << " " << pos.y << endl;
// Point의 멤버객체 x,y에 접근 가능한 이유는 friend로 선언했기 때문
}
int main()
{
Point pos1(1, 2);
Point pos2(2, 4);
PointOP op;
ShowPointPos(op.PointAdd(pos1, pos2));
ShowPointPos(op.PointSub(pos2, pos1));
return 0;
}
C에서의 static
- 전역변수의 static : 선언된 파일 내에서만 참조를 허용한다.
- 함수 내에서 선언된 static : 한번만 초기화되며, 함수를 빠져나가도 소멸되지 않는다.
#include <iostream>
using namespace std;
void Counter()
{
static int cnt; // 0으로 초기화된다. 한 번 실행되면 다시 실행되지 않는다.
cnt++;
cout << "Current cnt : " << cnt << endl;
}
int main()
{
for (int i = 0; i < 10; i++)
Counter();
return 0;
}
static 변수의 초기화는 따로 초기화하지 않으면 무조건 0이고, 딱 한번 실행된다.
#include <iostream>
using namespace std;
int a = 0;
int b = 0;
class SoSimple {
public:
SoSimple() {
a++;
cout << a << "번째 SoSimple 객체" << endl;
}
};
class SoComplex{
public:
SoComplex() {
b++;
cout << b << "번째 SoComplex 객체 " << endl;
}
SoComplex(SoComplex& copy)
{
b++;
cout << b << "번째 SoComplex 객체 " << endl;
}
};
int main()
{
SoSimple sim1; // 1
SoSimple sim2; //2
SoComplex com1; //1
SoComplex com2 = com1; //2
SoComplex(); // 3
}
static을 쓰지 않고 전역변수로 클래스들의 객체를 사용하였다. 이 코드는 private하게 객체를 지켜줄 방안이 마련되어있지 않아 문제를 일으킬 수 있다. 따라서 a를 SoSimple클래스의 static 멤버로, b를 SoComplex 클래스의 static멤버로 선언해보겠다.
재구현해보자!
#include <iostream>
using namespace std;
class SoSimple {
private:
static int a;
public:
SoSimple()
{
a++;
cout << a << "번째 SoSimple 객체" <<endl;
}
};
int SoSimple::a = 0; //static 멤버 변수 초기화
class SoComplex {
private:
static int b;
public:
SoComplex() {
b++;
cout << b << "번째 SoComplex 객체 " << endl;
}
SoComplex(SoComplex& copy)
{
b++;
cout << b << "번째 SoComplex 객체 " << endl;
}
};
int SoComplex::b = 0;
int main()
{
SoSimple sim1; // 1
SoSimple sim2; // 2
SoComplex cmx1; //1
SoComplex cmx2 = cmx1; //2
SoComplex(); //3
return 0;
}
static 멤버 변수는 메모리에 할당이 이미 이뤄진 변수이다. 따라서 int SoSimple::a = 0; 처럼 초기화 문법을 다음과 같이 별도로 진행한다.
다음과 같이 public으로 static변수를 선언하면 main함수에서도 그냥 쓸 수 있다.
#include <iostream>
using namespace std;
class SoSimple {
public:
static int a;
public:
SoSimple()
{
a++;
}
};
int SoSimple::a = 0; //static 멤버 변수 초기화
int main()
{
cout << SoSimple::a << "번째 SoSimple 객체" << endl; // 0
SoSimple sim1;
SoSimple sim2;
cout << SoSimple::a << "번째 SoSimple 객체" << endl; //2
cout << sim1.a<< "번째 SoSimple 객체" << endl; //2
cout << sim2.a << "번째 SoSimple 객체" << endl;//2
return 0;
}
sim1.a 와 sim2.a는 각자의 멤버변수를 가르키는 것 같지만 사실을 같은 메모리 공간을 가르킨다.
#include <iostream>
using namespace std;
class SoSimple
{
private:
int num1;
static int num2;
public:
SoSimple(int n)
: num1(n)
{
}
static void Adder(int n) // 클래스의 멤버가 아니다. 따라서 멤버 변수에 접근할 수 없다.
{
num1 += n; // static 으로 선언되지 않은 멤버 변수의 접근 x
num2 += n; // static 멤버 변수는 호출 가능하다.
}
};
int SoSimple::num2 = 0;
int main()
{
}
다음 코드는 에러를 포함한다. static 함수 Adder은 Class SoSimple의 멤버가 아닌데, 멤버 변수인 num1을 사용했기 때문이다. static 변수인 num2는 전역과 동일하기 때문에 에러가 발생하지 않는다.
#include <iostream>
using namespace std;
class Country {
public:
const static int a = 1;
const static int b = 2;
};
int main()
{
cout << "a : " << Country::a << endl;
cout << "a : " << Country::b << endl;
}
public으로 정의된 const static 변수는 main함수에서 다음과같이 간단히 출력이 가능하다.
mutable은 const 함수 내에서의 값의 변경을 예외적으로 허용하는 것이다.
#include <iostream>
using namespace std;
class SoSimple {
private:
int num1;
mutable int num2;
public:
SoSimple(int n1, int n2)
:num1(n1), num2(n2)
{
}
void Show() const
{
cout << num1 << "," << num2 << endl;
}
void Copy() const {
num2 = num1;
}
};
int main()
{
SoSimple sm(1, 2); // num1= 1 num2 = 2
sm.Show(); // 1,2
sm.Copy();
sm.Show(); // 1,1
//const 함수에서 값을 바꿨다?
return 0;
}
'Langauge > C++' 카테고리의 다른 글
Introduction to classes and objects #1 (0) | 2021.03.10 |
---|---|
[열혈 C++ 프로그래밍] Chapter 07(상속의 이해) (0) | 2021.03.01 |
[열혈 C++ 프로그래밍] Chapter05(복사 생성자) 정리 및 문제 해결 (0) | 2021.02.16 |
[열혈 C++ 프로그래밍] Chapter04(클래스의 완성) 정리 및 문제 해결 #2 (0) | 2021.02.14 |
[열혈 C++ 프로그래밍] Chapter04(클래스의 완성) 정리 및 문제 해결 #1 (0) | 2021.02.13 |