c++의 destructor에 관해서 질문있습니다요.

leesort의 이미지

class base{	
public:
	int a;	
	base dsp();
	base(const base &xx);
	base(){
                         cout << "base()"<< a<<endl;
	}
	~base(){};
};

base::base(const base &xx) 
{
	cout << "base(base)" << endl;
	a = xx.a;
}

base base::dsp()
{
	base ob;
	ob.a = 100;
	return ob;
}

void main()
{
	base p1;
	base p2 = p1.dsp();
	cout << p2.a << endl;
	return;
}

위의 코드에서요
1. base p2 = p1.dsp(); 가 c++에서는 내부적으로
base p2; p2.base(p1.dsp());로 처리되나요?

2. java와 다르게 base p1; 만으로 메모리에 p1크기만큼
allocation되나요?

3. dsp()안에서의 ob는 지역변수인데 왜 return이 잘되나요?

4. ~base(){};를 주석처리하면
cout << "base(base)" << endl; 이부분이 2번실행되는데,
왜 그런것일까요? 또 주석처리안했을때엔
한번 실행되는데 왜그럴까요? -_-

이제막 java에서 c,c++로 넘어가는데 도와주셔요. :oops:

죠커의 이미지

1. 예. 맞습니다. 이렇게 비효율적으로 처리되기 때문에 대입 연산자를 구현해서 한번에 처리할 수 있습니다. C++에서 대입은 대입일 뿐 초기화가 아닌 상황이 많습니다.

2. 아닙니다. 실제로 얼마나 할당될지는 구현마다 틀리지만 대체로 헤더 등의 정보가 포함이 되어 더 큰 양이 할당됩니다. 즉 C/C++에서 메모리 할당은 변수 하나 구조체 하나 보다는 객체 하나 이상이나 배열을 다루는 것이 더 적합합니다.

3. int abc(void) { return 3 }; 을 하면 3이라는 숫자가 리턴됩니까? 3을 초기 값으로 가지는 int 형 변수가 할당되어서 거기에 입력됩니다. ob 자체가 전달되는 것이 아닙니다.

4. 예전에 경험해보았는데 VC 6의 버그로 결론을 내렸던 걸로 기억합니다. 조금 더 근대적인 컴파일러로 바꿔 보십시요.

(기타)
5. void main()을 사용하지 마시고 int main()을 사용하세요. void main()은 "운영체제가 있는 환경"에서 표준에 맞지 않습니다. 많은 이들은 자의적으로 main을 해석하고 있지만 이는 잘못입니다.

6. 소멸자는 특별한 이유가 없다면 virtual으로 지정하세요. 흔히 C++의 객체지향은 포인터로 부모 클래스 변수를 잡고 자녀 클래스를 할당하는 방식으로 이루어 지는데 "소멸자"가 virtual이 아니면 문제가 생깁니다.

7. 생성자 내의 초기화는 Java 방식을 사용하지 마세요. 1번과 같은 문제가 생길 가능성이 있고, C++에서는 언어적으로 생성자를 위한 초기화 리스트를 지원하고 있습니다.

base::base(const base &xx) : a(xx.a)
{
   cout << "base(base)" << endl;
}

위의 형태로 변경하시는 것을 추천합니다.
leesort의 이미지

내공이느껴집니다. 답변 많은 도움이 되었습니다.


------------------------------------------
------------사진은 제가 아님----------------
------------------------------------------

doldori의 이미지

CN wrote:
1. 예. 맞습니다. 이렇게 비효율적으로 처리되기 때문에 대입 연산자를 구현해서 한번에 처리할 수 있습니다. C++에서 대입은 대입일 뿐 초기화가 아닌 상황이 많습니다.

제 생각에 OP께서는 이 초기화 구문이 디폴트 생성자+복사 생성자의 호출이냐고
물으신 듯합니다. 그렇다면 그 답은 "아니오"입니다. 이 초기화는 복사 생성자만
호출합니다.
그리고 대입 연산과는 관련이 없는데 대입 연산자를 말씀하신 이유는 무엇인지요?
leesort의 이미지

1. 그럼 c++에서
base p2 = p1.dsp(); 가
base p2; p2.base(p1.dsp());로 처리되고,

base p2; 는
base p2; p2.base()로 처리된다는 말씀이군요.

ps. java의 경우 base p2;만 할경우 p2 = null값을가지고 아직 메모리에
allocation이 되지 않는데 c++은 된다는 거군요.
그럼 java의 경우 base p2는 c++의 base *p2; 와 동일할것같기도 합니다만
얼핏듣기에 java에 pointer가 없는 것이아니라 모든 것이 pointer이다.
라고 들은적이 있기도...; :roll:


------------------------------------------
------------사진은 제가 아님----------------
------------------------------------------

doldori의 이미지

leesort wrote:
1. 그럼 c++에서
base p2 = p1.dsp(); 가
base p2; p2.base(p1.dsp());로 처리되고,

아닙니다.
base p2(p1.dsp());
로 처리됩니다. 즉 복사 생성자만 호출됩니다.
p2.base(p1.dsp())는 틀린 문법입니다.

leesort wrote:
base p2; 는
base p2; p2.base()로 처리된다는 말씀이군요.

p2.base()는 틀린 문법입니다. base p2; 라는 선언만으로 디폴트 생성자를 호출합니다.
kewlbear의 이미지

자바의 경우 base p2;는 base형 개체에 대한 참조 변수를 정의하는 것입니다. p2 = new base();를 할 때 개체가 생성되지요. 하지만 C++에서는 포인터나 참조형이 따로 있기 때문에 자바와는 좀 다릅니다. 자바에서는 모두 포인터라는 비유도 (primitive 형을 제외하면) 어느 정도 일리가 있습니다.

죠커의 이미지

잠결에 답변을 하다보니 헛소리가 많았습니다. leesort님께 죄송하고 doldori님에께 감사합니다.

이미 doldori님이 정확한 답변을 하셨지만 생성자 위주로 정리해보겠습니다.
base p1;
base의 기본 생성자가 호출됩니다.
base p2 = p1.dsp();
위의 구문에서 먼저 p1.dsp()가 실행됩니다. 그리고 base::dsp()속에 있는 base ob의 기본 생성자가 실행이 됩니다. 그리고 그 값을 기준으로 복사 생성자 base(const base &xx); 를 실행합니다.

그리고 C++에서는 int a = 3; 과 int a(3);이 동일하게 작동합니다. doldori님이 이야기 하신 base p2(p1.dsp());가 왜 그렇게 되는지 이해하실 수 있을 것입니다. (위의 글은 왜 저렇게 엉터리로 적은지 모르겠습니다. ;;;)

leesort wrote:
ps. java의 경우 base p2;만 할경우 p2 = null값을가지고 아직 메모리에
allocation이 되지 않는데 c++은 된다는 거군요.
그럼 java의 경우 base p2는 c++의 base *p2; 와 동일할것같기도 합니다만
얼핏듣기에 java에 pointer가 없는 것이아니라 모든 것이 pointer이다.
라고 들은적이 있기도...; :roll:

JAVA의 경우에도 int a; 의 경우에는 바로 할당되지 않습니까? JAVA는 프리미티브 자료형과 클래스가 다른 형태로 작동하는데 비해서 C++에서는 동일한 방법으로 작동하는 것입니다. 자바와 같은 형태로 사용하고 싶을 때는 레퍼런스나 포인터를 명시적으로 지정해주셔야 합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.