class 이름
{
private:
//멤버 목록
public:
//멤버목록
}
생성자 : 생성자 초기화 리스트
소멸자
class MyClass
{
public:
int m;
int m2;
MyClass(): MyClass(1, 1)
{
//초기화됨
}
MyClass(int m, int m2): m{m}, m2{m2}
{
//대리생성자로 멤버들이 초기화됨
}
void Setm(int x)
{
m = x;
}
void Print()
{
std::cout << m << "," << m2 << std::endl;
}
};
int main() {
const int x = 1;
//기본 생성자로 초기화된 상수 인스턴스
const MyClass c1;
const MyClass c2(2, 2);
//대리생성자로 멤버 변수로 초기화되서 c2라는 상수 인스턴스가 만들어짐
// c1.m = 3; 불가능 상수라서
/*c1.Setm(3);
this에 &c1이 들어오는데 c1은 const객체->
그러면 const객체의 멤버는 변경할 수 없음
상수객체는 사용 불가능함
c1.Print();
이미 this에 &c1 상수 객체가 넘어간 것 ->
상수 객체가 넘어간다는 것은 값을 바꾸는 것이 아니라 사용만 하더라도 위험요소가 존재함
문법적인 위험 요소가 남게 됨 (상수라는 표기에 올바르지 않음-> 초기화되면 바꿀 수 없다는 전재조건)
*/
}
멤버 함수를 못 쓰나요?
- 오직 하나 : 상수 멤버 함수
- 멤버 함수가 인스턴스를 바꾸지 않는다는 것
class<클래스명>
{
...
static<타입><변수명>;
};
<타입><클래스명>::<변수명>;
class MyClass
{
//클래스 선언 -> 타입 선언과 같음
//실체가 없음(인스턴스가 만들어지기 전까지는) 개념적인 것
public:
static int mValue;
//정적 멤버변수 : 멤버변수가 인스턴스에 종속되지 않는 클래스 변수
};
int MyClass::mValue;
//선언이 위에 있기 때문에 정의가 필요함
int main()
{
MyClass c1;
//c1.mValue = 1;
//c1이라는 인스턴스의 멤버이기 때문에 이런 방식은 사용 불가
//인스턴스를 찍어내는 클래스에 속해야함
MyClass::mValue = 1;
std::cout << MyClass::mValue << std::endl;
}
클래스 활용 방법
int main()
{
{
MyClass c1, c2, c3;
//3번의 생성자가 불림 -> this->가 아니라 myclass::라서 한 번 만들고 나면 유지됨
//그래서 갯수가 3이 나옴
std::cout << MyClass::mValue << std::endl;
}
std::cout << MyClass::mValue << std::endl;
//0이 나옴
//이런 개념을 이용해서 함수가 몇번 불리는지 확인해서 최적화에 사용함
}
class OrderTicket
{
private:
static int mID;
public:
void Normal() {
this->mID;
}
static int Publish() //static 멤버 함수
{
return ++mID;
//this->mID가 아니고 OrderTicket::mID
//스테틱 함수에서는 this 못 씀
}
//리소스를 관리하는 용도로 manager개념 사용
};
int OrderTicket::mID {};
int main()
{
OrderTicket C1;
/*std::cout << C1.Publish() << std::endl;
std::cout << C1.Publish() << std::endl;
std::cout << C1.Publish() << std::endl;*/
std::cout << OrderTicket::Publish() << std::endl;
std::cout << OrderTicket::Publish() << std::endl;
std::cout << OrderTicket::Publish() << std::endl;
}
//friend class
class Sword
{
friend class Warrior;
private:
int damage;
public:
Sword(int dmg): damage {dmg}
{
}
};
class Warrior
{
public:
void AttackWith(Sword &s) {
std::cout << "칼로" << s.damage << "피해줌" << std::endl;
//소드가 워리어를 친구로 지정해야함
//숨기는 사람이 공개 여부를 지정해야함
}
};
int main() {
Sword knife {10};
Warrior w;
w.AttackWith(knife)
knife. //친구에게만 공개됨 ->warrior 클래스 에게만 공개되는 것
}
class Sword; //이름만 알려줌
class Warrior
{
public:
void AttackWith(Sword &s);
//정의를 sword뒤로 보냄 ->
};
//friend class
class Sword
{
//friend class Warrior;
friend void Warrior::AttackWith(Sword &sword);
//친구 멤버 함수 : Sword가 선언될 때 warrior가 뭔지 모르기 때문에 컴파일 에러
//함수의 전방 선언처럼 미리 선언하기
//멤버 함수가 아니고 전역 함수 Sword 클래스와는 아무 상관없음
friend void Upgrade(Sword &sword)
{
int old = sword.damage;
sword.damage = old * 2;
//어쩔 수없이 멤버에 접근해야함 -> 이 함수를 친구로 지정함
}
private:
int damage;
public:
Sword(int dmg): damage {dmg}
{
}
};
int main() {
Sword knife {10};
Warrior w;
w.AttackWith(knife);
//knife.
//친구에게만 공개됨 ->warrior 클래스 에게만 공개되는 것
Upgrade(knife);
w.AttackWith(knife);
}
void Warrior::AttackWith(Sword &s)
{
std::cout << "칼로" << s.damage << "피해줌" << std::endl;
//소드가 워리어를 친구로 지정해야함
//숨기는 사람이 공개 여부를 지정해야함
}
class Point2D
{
private:
int my;
int mx;
public:
Point2D():Point2D(0, 0){}
Point2D(int x, int y):mx(x), my(y)
{
}
void Print()
{
std::cout << "(" << mx << "," << my << ")" << std::endl;
}
friend Point2D operator+(const Point2D& operand1, const Point2D& operand2);
};
Point2D operator+(const Point2D& operand1, const Point2D& operand2)
{
Point2D result;
result.mx = operand1.mx + operand2.mx;
result.my = operand1.my + operand2.my;
//친구함수로 프라이빗 멤버에 접근
return result;
}
int main() {
Point2D pt1(2, 3), pt2(3, 4);
pt1.Print();
pt2.Print();
Point2D pt3;
///이 기능이 연산자 오버로딩
pt3 = pt1 + pt2;
//pt3 = operator+(pt1, pt2);
pt3.Print();
Point2D pt4;
pt4 = (pt1 + pt2) + pt3;//참조형 - rvalue라서 에러가남 -> const를 붙여서 해결(const 참조형) -> const는 정해진 것은 아님 rvalue를 사용할 때만 사용
}
///r-value : anonymous object (무명객체, 익명객체)
class MyClass
{
public:
int value;
MyClass(int v): value {v}
{
std::cout << "[construct]:" << value << std::endl;
}
private:
};
MyClass operator*(MyClass op1, MyClass op2) {
///MyClass result(0);//객체 생성
///result.value = op1.value * op2.value;
///
///return result;
return MyClass(op1.value + op2.value);
//연산자의 결과로 객체가 생성될 수 있음
//이게 무명객체
}
MyClass Square(MyClass x)
{
return x * x;
}
int plus(int x)
{
//int temp = x + x;
//return temp;
//rvalue :이름이 없는 객체
}
int main()
{
MyClass x {2}, y {0};
y = Square(x);
std::cout << y.value << std::endl;
//객체가 총 3번 생성됨 ->> 2 , 0 , 0 >> 4
}