보조자료 6.Static 멤버와 const 멤버 클래스와 const 클래스와 static 연결리스트프로그램예 Jong Hyuk Park
클래스와 const Jong Hyuk Park
복습 : Const 키워드왜사용? C 의 const (1) const double PI=3.14; PI=3.1415; // 컴파일오류 const int val; val=20; // 컴파일오류 3
C 의 const (1) int n=10; const int* pn=&n; *pn=20; // 컴파일오류 int n1=10; int n2=20; int* const pn=&n1; *pn=20; pn=&n2; // 컴파일오류 4
5 #include<iostream> using std::endl; 멤버변수의상수화 객체생성시고유한상수값을지정하면좋은경우가있음예 ) 학생의학번 class Student const int id; int age; char name[20]; char major[30]; public: Student(int _id, int _age, char* _name, char* _major) id=_id; //error age=_age; strcpy(name, _name); strcpy(major, _major); ; void ShowData() cout<<" 이름 : "<<name<<endl; cout<<" 나이 : "<<age<<endl; cout<<" 학번 : "<<id<<endl; cout<<" 학과: "<<major<<endl; int main() Student Kim(200577065, 20, "Kim Gil Dong", "Computer Eng."); Student Hong(200512065, 19, "Hong Gil Dong", "Electronics Eng."); Kim.ShowData(); cout<<endl; Hong.ShowData(); 컴파일에러 상수값을생성자에서초기화하여발생 Member initializer 사용 Const 멤버변수초기화
멤버변수의상수화 (2) Student(.): id(_id) // 멤버변수 id 를멤버변수 _id 로초기화함 #include<iostream> using std::endl; 6 class Student const int id; int age; char name[20]; char major[30]; public: Student(int _id, int _age, char* _name, char* _major) : id(_id), age(_age) strcpy(name, _name); int main() strcpy(major, _major); void ShowData() cout<<" 이름 : "<<name<<endl; cout<<" 나이 : "<<age<<endl; Kim.ShowData(); cout<<" 학번 : "<<id<<endl; cout<<endl; cout<<" 학과 : "<<major<<endl; Hong.ShowData(); ; Initializer 는생성자함수호출전에초기화됨. Student Kim(200577065, 20, "Kim Gil Dong", "Computer Eng."); Student Hong(200512065, 19, "Hong Gil Dong", "Electronics Eng.");
const 멤버함수 멤버함수의상수화 함수내부에서멤버변수의값을변경할수없음 이함수내에서상수화되지않은함수의호출을허용하지않음 멤버변수의포인터의리턴을허용하지않음 사용예 void ShowData() const cout<<" 이름 : "<<name<<endl; cout<<" 나이 : "<<age<<endl; cout<<" 학번 : "<<id<<endl; cout<<" 학과 : "<<major<<endl; 7
const 멤버함수예 (1) #include <iostream> using std::endl; class Count int cnt; public : Count() : cnt(0) int* GetPtr() const return &cnt; // Compile Error int main() Count count; count.increment(); count.showdata(); void Increment() cnt++; ; void ShowData() const ShowIntro(); // Compile Error cout<<cnt<<endl; void ShowIntro() cout<<" 현재 count 의값 : "<<endl; 8
const 멤버함수예 (2) #include <iostream> using std::endl; class Count int cnt; public : Count() : cnt(0) const int* GetPtr() const return &cnt; void Increment() cnt++; 9 void ShowData() const ShowIntro(); cout<<cnt<<endl; void ShowIntro() const cout<<" 현재 count의값 : "<<endl; int main() Count count; count.increment(); count.increment(); count.showdata(); ;
const 객체 const 객체 객체도생성과동시에상수화하는것이가능 데이터의변경이허용되지않는객체 const 함수이외에는호출불가 const 와함수오버로딩 const도함수오버로딩조건에포함 void function(int n) const..... void function(int n)..... 10
const 멤버함수예 11 #include <iostream> using std::endl; class AAA int num; public : AAA(int _ num) : num( (_ num) void Add(int n) num+=n; void ShowData() cout<<num<<endl; ; int main() const AAA aaa(10); aaa.add(10); // Compile Error aaa.showdata(); // Compile Error 출력값? #include <iostream> using std::endl; class AAA int num; public : AAA(int _num) : num(_num) void ShowData() cout<<"void ShowData() 호출 "<<endl; cout<<num<<endl; void ShowData() const cout<<"void ShowData() const 호출 "<<endl; cout<<num<<endl; ; int main() const AAA aaa1(20); AAA aaa2(70); aaa1.showdata(); // void ShowData() const 호출 aaa2.showdata(); // void ShowData() 호출
const 멤버함수예 12 #include <iostream> using std::endl; class AAA int num; public : AAA(int _ num) : num( (_ num) void Add(int n) num+=n; void ShowData() cout<<num<<endl; ; int main() const AAA aaa(10); aaa.add(10); // Compile Error aaa.showdata(); // Compile Error 출력값? void ShowData() const 호출 20 void ShowData() 호출 70 #include <iostream> using std::endl; class AAA int num; public : AAA(int _num) : num(_num) void ShowData() cout<<"void ShowData() 호출 "<<endl; cout<<num<<endl; void ShowData() const cout<<"void ShowData() const 호출 "<<endl; cout<<num<<endl; ; int main() const AAA aaa1(20); AAA aaa2(70); aaa1.showdata(); // void ShowData() const 호출 aaa2.showdata(); // void ShowData() 호출
클래스와 static Jong Hyuk Park
정적멤버 (static member) Static 멤버의등장 전역변수와전역함수를일부대처하기위해등장 Static 키워드의효과 모든객체가공유할수있는멤버 14
정적멤버 (static member) 정적멤버 같은클래스형으로선언된여러객체들이동일한하나의자료를공유 클래스의정의시멤버를 static 이란키워드로정의 클래스내에선언된정적멤버는정적멤버가선언된클래스로사용영역이제한된전역변수 (global variable) 클래스내에서정적멤버를선언할때정적멤버자체가정의되는것은아니기때문에클래스밖에서정적멤버를정의하는선언필요 모든정적멤버변수는특별히초기값을명시하지않는한 0으로초기화 15
전역변수가필요한상황 16 예 ) 객체가생성될때마다 n 번째 Person 객체생성 출력프로그램 /* PersonCount1.cpp */ #include<iostream> using std::endl; int count=1; class Person char name[20]; int age; public: Person(char* _name, int _age) ; strcpy(name, _name); age=_age; cout<<count++<<" 번째 Person 객체생성 "<<endl; void ShowData() cout<<" 이름 : "<<name; cout<<" 나이 : "<<age; int main(void) Person p1("lee", 13); Person p2("hong", 22); 1 번째 Person 객체생성 2 번째 Person 객체생성 전역변수 count는 Person 클래스에종속적임그럼에도불구하고, 다른영역에서적급할위험이존재
17 /* PersonCount2.cpp */ #include<iostream> using std::endl; dl class Person public: ; char name[20]; int age; int count; Person(char* _name, int _age) count=1; int main(void) Person p1("lee", 13); Person p2("hong", 22); // 멤버변수는생성과동시에초기화안되기때문에초기화함 strcpy(name, _name); age=_age; cout<<count++<<" 번째 Person 객체생성 "<<endl; void ShowData() cout<<" 이름 : "<<name; cout<<" 나이 : "<<age; 전역변수 count는 Person 클래스내에서만접근을허용 결과는? 1번째 Person 객체생성 1 번째 Person 객체생성 현재메모리구조
정적멤버 (static member) 모든 Persson 객체가변수 Count 를공유하도록해주어야함 18
/* PersonCount3.cpp */ #include<iostream> using std::endl; class Person char name[20]; int age; static int count; public: Person(char* _name, int _age) strcpy(name, _name); age=_age; age; cout<<count++<<" 번째 Person 객체생성 "<<endl; void ShowData() cout<<" 이름 : "<<name; cout<<" 나이 : "<<age; ; int main(void) Person p1("lee", " 13); Person p2("hong", 22); 1 번째 Person 객체생성 2 번째 Person 객체생성 19 int Person::count=1; // static 멤버초기화
정적멤버사용예 (1) #include <iostream> class Point static int xval, yval; // 정적멤버선언 12, 6 public: 12, 6 setpt(int x, int y) xval = x; yval = y; void showxy() cout << xval << ", " << yval << '\n'; ; 전용부분멤버 xval, yval을정적멤버 int Point::xval, Point::yval; // 정적멤버정의 int main() Point pt1, pt2; 로선언하고클래스밖에서통용범위지정연산자 :: 로소속클래스를명시하여정의하면객체 pt1, pt2가자료를공유하여같은값을출력한다. pt1.setpt(12,6); pt1.showxy(); pt2.showxy(); 객체 pt1 static int xval,yval 객체 pt2 20
정적멤버사용예 (2) #include <iostream> class Test public: static int n; // 정적멤버선언 void setn(int a) n = a; void shown() cout << n << '\n'; ; int Test::n; // 정적멤버정의 int main() Test x,y; 88 88 정적멤버는클래스밖에서정의되므로객체와관계없이직접참조될수있다. 이예에서 n을특정객체와무관하게 88로지정할수있다. Test::n = 88; // 정적멤버참조 x.shown(); y.shown(); 21
정적멤버 (static member) static 멤버의특징 클래스변수, 클래스함수라한다. 객체의멤버로존재하지않는다. main 함수호출이전에메모리공간에올라가서초기화 ( 전역변수와동일 ) 선언된클래스의객체내에직접접근허용 static 멤버초기화문으로초기화해야함 22
정적멤버 (static member) class AAA int val; static int n; int main(void) AAA a1(10); a1.showdata(); public: AAA a2(20); AAA(int a=0) a2.showdata(); val=a; n++; void ShowData() cout<<"val: "<<val<<endl; cout<<"n: "<<n<<endl; 출력결과? ; int AAA::n=1; 23
explicit & mutable explicitp 명시적호출만허용한다. 자주사용되지않으나, 객체생성관계를분명히 하고자할때사용 mutable const 에예외를둔다 상수화된멤버함수라할지라도데이터변경가능 24
explicit & mutable /* explicit.cpp pp */ #include<iostream> using std::endl; class AAA public: ; explicit AAA(int n) cout<<"explicit AAA(int n)"<<endl; int main(void) AAA a1=10; 10; // AAA a1(10) 묵시적변환 error 발생 25
explicit & mutable /* mutable.cpp */ #include<iostream> using std::endl; 26 class AAA private: mutable int val1; int val2; public: void SetData(int a, int b) const val1=a; // val1이 mutable이므로 OK! val2=b; // Error! ; int main(void) id) AAA a1; a1.setdata(10, 20);
Jong Hyuk Park