~cpp
#include <iostream>
using namespace std;
class Foo{
public:
int id;
Foo(){
static idSequance = 0;
id = idSequance++;
cout << "Create! id = " << id << endl;
}
void die(){
cout << "I suicide. Id is " << id << endl;
delete this; // 자신 삭제
}
void sayMyId(){
cout << "My Id is no " << id << endl;
}
void sayHello(){
cout << "say Hello" << endl;
}
};
int main(int argc, char** argv)
{
cout << endl << ":::::: Case 1 - 동적할당 " << endl;
Foo* foo1 = new Foo();// Create! 를 출력한다.
foo1->sayHello(); // Hello 출력
foo1->sayMyId(); // id 출력
foo1->die(); // 객체 삭제
foo1->sayHello(); // 동작 가능
foo1->sayMyId(); // 동작 가능
// id 확인차
cout << endl << ":::::: Case 2 - id 확인" << endl;
Foo* foo2 = new Foo();// Create! 를 출력한다.
foo2->sayHello(); // Hello World 출력
foo2->sayMyId(); // id 출력
foo2->die();
foo2->sayHello();
foo2->sayMyId();
cout << endl << ":::::: Case 3 - 포인터 NULL로 하고 메소드 호출하기 " << endl;
Foo* foo3 = NULL; // 자세한 설명보세요.
foo3->sayHello(); // Hello 를 출력한다.
//foo3->sayMyId(); // debug, release 모두 동작할 수 없다.
//foo3->die(); // debug, release 모두 동작할 수 없다.
cout << endl << ":::::: Case3 - 지역변수로 선언" << endl;
Foo foo4;
foo4.sayHello(); // Hello World 출력
foo4.sayMyId(); // id 출력
foo4.die(); // debug mode에서 assertion error
foo4.sayHello(); // release 에서 동작 가능
foo4.sayMyId(); // release 에서 동작 가능
cout << endl;
return 0;
}
결과는 다음과 같이 출력됩니다. 비교해보면서, 생각해 보고 이해가지 않는다면 자세한 설명을 보세요.~cpp :::::: Case 1 - 동적할당 Create! id = 0 say Hello My Id is no 0 I suicide. Id is 0 say Hello My Id is no 3604872 :::::: Case 2 - id 확인 Create! id = 1 say Hello My Id is no 1 I suicide. Id is 1 say Hello My Id is no 3604872 :::::: Case 3 - 포인터 NULL로 하고 메소드 호출하기 say Hello :::::: Case3 - 지역변수로 선언 Create! id = 2 say Hello My Id is no 2 I suicide. Id is 2 say Hello My Id is no 2 Press any key to continue
~cpp Foo* foo1 = new Foo(); // Create! 를 출력한다. foo1->sayHello(); // Hello World 출력 foo1->sayMyId(); // id 출력 foo1->die(); // 죽였다. foo1->sayHello(); // 호출이 된다? foo1->sayMyId(); // 이것도..--;
~cpp Foo* foo2 = NULL; // 자세한 설명보세요. foo2->sayHello(); // Hello 를 출력한다.(음--;) foo2->sayMyId(); // debug, release 모두 동작할 수 없다. foo2->die(); // debug, release 모두 동작할 수 없다.
~cpp
class Foo{
public:
int id; // <- 이 부분의 정보 입니다.
};
C++은 Strong typed language 이므로 컴파일 시간에 모든 형이 선언되고, 사용되는 것을 검증할 수 있습니다. 하지만 이는 다음과 같은 지역 변수에 국한합니다. ~cpp Foo foo4;new 키워드로 할당시에는 runtime 에 class 의 instance 를 찍어 낼수 있어야 합니다. 이를 위해 프로그램 안에는 위의 id가 int 라는 정보를 담는 class의 "class 틀" 정보를 담는 곳이 필요합니다.
~cpp
class Foo{
public:
int id;
void sayMyId(){
cout << "My Id is no " << id << endl;
}
};
라는 함수는 각 instance의 id 라는 인자에 접근합니다. ~cpp Foo::sayMyId() 같은 아무런 인자 없는 함수의 실행코드가 함수 선언 영역에 세팅된다면, id 라는 인자에 접근할수 없습니다. ~cpp Foo:sayMyId()라는 함수 실행 코드가 함수 영역에 선언될때 컴파일러가
~cpp Foo:sayMyId(Foo* x)라는 형태의 함수로 선언하고, 실행할수 있도록 만듭니다. 그리고, 호출한다면
~cpp Foo* 부분에 ~cpp foo1->sayMyId(foo1);형태로 함수 포인터를 세팅해서 함수 코드를 실행합니다.
~cpp Foo* foo1 = new Foo(); // Create! 를 출력한다. foo1->sayHello(); // Hello 출력 foo1->sayMyId(); // id 출력 foo1->die(); // 객체 삭제 foo1->sayHello(); // 동작 가능 foo1->sayMyId(); // 동작 가능
~cpp Create! id = 0 say Hello My Id is no 0 I suicide. Id is 0 say Hello // 객체 삭제(delete this)후 실행 코드 My Id is no 3604872 // 객체 삭제(delete this)후 실행 코드
~cpp sayHello() 와 sayMyId() 일겁니다. 둘째 설명의 member 함수를 호출하는 메커니즘을 이해했다면 ~cpp sayHello() -> sayHello(Foo*) sayMyId() -> sayMyId(Foo*)형태로 호출된다는 것을 짐작할 수 있을 겁니다. 하지만 두 함수는 다른 점이 있습니다.
~cpp sayMyId() 는 접근한다는 점이지요.~cpp say Hello 객체 삭제(delete this)후 실행 코드 My Id is no 3604872 객체 삭제(delete this)후 실행 코드instance에 사용되었던 메모리는, 해당 process의 가용 메모리로 돌아가지, 접근 금지 영역으로 세팅되지 않습니다. 이 부분은 delete this 시 해당 instance 영역의 값을 어떻게 "청소"하느냐에 따라서, 플랫폼 별로 다르게 나옵니다.
~cpp delete x라는 코드는 x의 값을 변화시키지 않습니다. 변화시킬수 없습니다. 이유는 call by value 로 넘어온 x의 값을 NULL로 변경시켜봤자, 영향 받지 않는 코드가 경우가 있기 때문에, 변화시킬 필요성이 없습니다.
~cpp Foo* foo2 = NULL; // 자세한 설명보세요. foo2->sayHello(); // Hello 를 출력한다.이 코드의 결과는
~cpp say Hello과 같이 잘 동작합니다. 호출 형태가
~cpp Foo::sayHello(foo2) -> Foo::sayHello(NULL)이 된것이고, sayHello 내에는 pointer 값 NULL 을 이용한 접근이 없으므로 아무런 에러가 발생하지 않습니다.
~cpp
// Main.java file
class Foo{
public int a;
void sayHello(){
System.out.println("Hello");
}
}
public class Main {
public static void main(String[] args) {
Foo foo= null;
foo.sayHello();
}
}
이를 실행하면, 다음과 같은 exception을 출력합니다. 이는 Java Language Specification 2nd(http://java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html) (3rd가 아직 안나왔군요.) 와 jvm specification(http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html)을 참고하세요.~cpp java.lang.NullPointerException at Main.main(Main.java:19) Exception in thread "main"