자바 하다 c&c++ 할려니 험난하네요.

emptynote의 이미지

자바 하다 c&c++ 할려니 험난하네요.

가장 어려운것이 자바의 가비지 컬렉션에 익숙하기에,

변수 scope 를 무시한? 코딩을 하다가 왜 안되지 하네요.

static이 자바의 static과도 같으면서도 다르네요.

예로 아래 같이 a.cpp, b.cpp, main.cpp, common.h 로 구성한다고 할때

static 변수로 common.h에 하나 선언을 합니다.

그리고 실행을 하면

jhwon73@jhwon73-G41D3:~/sample/scope_var$ ./test_scope_var
call testd
call testd
call testA
call testB

저는 당연히 static이니깐 testD가 1번만 호출될거라 기대를 하였지만 2번 호출이 되었네요.
아직도 전 왜 2번 호출 되는가? 미궁에서 헤메고 있습니다.
그래서, 계속 달리고 달리고 달립니다.
------------------------
jhwon73@jhwon73-G41D3:~/sample/scope_var$ cat main.cpp
#include

class testA {
public:
testA();
};
class testB {
public:
testB();
};
int main(int argc, char *argv[]) {
testA test_a;
testB test_b;
}
jhwon73@jhwon73-G41D3:~/sample/scope_var$ cat a.cpp
#include "common.h"

class testA {
public:
testA();
};

testA::testA() {
std::cout << "call testA" << std::endl;
}
jhwon73@jhwon73-G41D3:~/sample/scope_var$ cat b.cpp
#include "common.h"

class testB {
public:
testB();
};

testB::testB() {
std::cout << "call testB" << std::endl;
}

jhwon73@jhwon73-G41D3:~/sample/scope_var$ cat common.h
#ifndef COMMON_H
#define COMMON_H
#include

static class testD {
public:
testD() {
std::cout << "call testd" << std::endl;
}
} gsTest;
#endi

klyx의 이미지

전역 네임스페이스(아무것도 없는 곳)에 변수나 함수를 static으로 선언한다는 것은,
다른 파일에 같은 이름의 변수나 함수가 있어도 그거랑은 상관없이, 선언된 내용은 해당 오브젝트파일내에서만 유효하다는 뜻ㅇㅂ니다.
아마 기대하신 static은 특정 스코프안에서 static으로 선언된 변수에 대한 내용같습니다.
참고로 해더파일은 아무것도 특별한 기능이 없습니다.
해더파일을 include하는 것은, 해당 해더파일을 그위치에 그대로 복사해서 붙여넣는것과 동일합니다.
따라서 gsTest라는 변수가 static으로 include된만큼 선언됩니다.
이것은 extern에 대비되는 개념입니다.

한 변수를 여러곳에서 공유해서 쓰고싶은 것이라면, extern이나 C++답게 static 멤버변수(ex:싱글톤)을 이용하시면 됩니다.

p.s. 저는 개인적으로 C++만 쓰다가 Java를 쓸려니, GC와 call-by-reference 때문에 정신이 하나도 없더군요.
뭔가 제가 알지 못하는 곳에서 일이 굴러간다는게 영꺼림직한 느낌이었습니다.
하나만쓰다보면 다른거에 적응하기 쉽지 않네요.

jeongheumjo의 이미지

저는 자바를 처음 보거든요.
C++ 은 문법정도를 파악한 정도이고 C 에만 익숙한 상태예요.
그런데 자바코드를 보니 C++ 과 다른 점이 너무 많아 놀랐습니다.
제 느낌은 "C++을 자바처럼 코딩하는 습관을 들이는 것이 좋겠다" 입니다.
자바는 OOP 스타일로 구현하기 쉽게 언어가 만들어진 것 같은데 C++ 은 실상 프로그래머의 코딩 습관이나 디자인에 따라 완전 절차적일 수도 있고 완전 OOP 일 수도 있거든요.
또 하나의 느낌은 "C++ 을 잘 하기 위해서라도 자바를 공부해야겠다... 라는 것."
자바를 잘 하기 위해서 C++을 공부할 필요는 없을 것 같아요..
제 개인적 느낌이었네요..

C++ 공부에 추천드릴 만한 책은 윤성우씨의 열혈강의 C++ 입니다.
단, 그 책은 C를 잘 아는 사람을 대상으로 씌였습니다.
님에게는 자바를 잘 아는 사람에게 설명하는 책이었으면 더 좋겠다는 느낌입니다만...그런 책은 제가 잘 모르겠네요...

위 코드를 봤습니다.
static 의 용법이라면 C 에서는 두가지로 쓰입니다.
함수 내의 변수를 선언하는 경우,
전역 함수나 변수를 선언하는 경우.
이 부분은 C++ 에까지 이어집니다.
함수 내의 변수를 선언하는 경우 - 는 그 변수를 전역변수화 합니다. 단 그 변수로의 접근은 함수 내로 제한됩니다.
전역 함수나 변수를 선언하는 경우 - 는 그 전역 함수나 변수가 다른 .c 혹은 .cpp 파일을 컴파일 할 때에 은닉되게 됩니다.

위 코드에서 사용하신 것은 "전역 함수나 변수를 선언하는 경우"에 해당합니다. 여기서 주의하실 점은 클래스를 선언하는 경우는 static 키워드를 사용하는 방법 대신 다른 방법을 쓴다는 것입니다. 물론 C++ 은 C 의 문법을 승계하기 때문에 클래스의 전역 인스턴스를 선언 할 때 static 키워드를 쓸 수 있습니다. 그렇게 되면 마찬가지로 컴파일할 때 해당 .cpp 파일을 컴파일 할 때에만 그 이름이 유효하고 다른 .cpp 파일을 컴파일 할때는 그 인스턴스가 보여지지 않을 것입니다.
위에 그 객체의 생성자가 두 번 호출된 것은 그 객체 생성이 두번 되었기 때문으로 보입니다. static 키워드가 있는 선언이 헤더파일에 있으신데, 그 헤더파일을 인크루드하는 .cpp 파일이 두개 이고 각 .cpp 파일에서 인스턴스가 하나씩 만들어 졌을 겁니다.

이렇게 하는 것은 두가지 면에서 오류가 있는 코드 입니다.
우선은 변수선언(인스턴스 선언)은 헤더파일에서 하지 않는 것이 좋은 습관입니다. 그렇게 해버리면 헤더파일이 인크루드 될 때 마다 인스턴스가 생기도록 코드하게 되기 때문입니다. 변수든 인스턴스든 객체의 생성은 .cpp 에서 하는 게 좋습니다.
또 하나는 C++ 에서는 "전역 함수나 변수를 선언하는 경우"에 C 스타일의 static 키워드를 사용하는 방식은 지양된다는 겁니다. 물론 틀린 코딩은 아니지만 C++ 에서는 이런 목적을 위해 이름없는 네임스페이스를 사용합니다. 그러니까 static 으로 선언할 변수나 인스턴스들은 몽땅 이름없는 네임스페이스에 넣어둡니다.

이상 짧은 지식으로 설을 풀어봤네요...
좋은 명절 되세요..

jeongheumjo의 이미지

님 C 에서 전처리과정과 헤더파일을 #include 하는 부분에 대해 공부하신다면 좋을 것 같습니다. 님의 문제는 C++ 보다는 '전처리과정과 헤더파일을 #include 하는' 문제 같아서요..
자바에서는 그런 과정이 없군요.
저는 지금 님과 반대 과정으로 자바를 공부하며 신기해 하는 중입니다.

kaeri17의 이미지

class선언 뿐만 아니라 classD의 instance를 두번 만드셨습니다. 인클루드를 하면서 .h가 두번 인클루드 되었기 때문이고요, 자바나 C++이나 언어에 대하여 명확한 이해를 바탕으로 코딩하시면 실수를 최대한 줄일 수 있습니다만... C++은 원체 문법이 복잡하므로 명확하게 이해를 하기 쉽지 않죠. 그래서 좋은 레퍼런스가 The C++ programming language입니다. 각각문법의 사용법 뿐만 아니라 왜 이런식으로 사용하는지를 친정히 설명을 하고 있죠. 조금 어렵긴 하지만.