C++ 에서 class의 reference member 위험성...

레모네이드의 이미지

class some
{
public:
    int* p;
 
    some()
    {
        printf("create some\n");
        p = new int;
        *p= 10;
    }
    ~some()
    {
        *p = 20;
        delete p;
        p = 0;
        printf("destruct some\n");
    }
};
 
class any
{
public:
    some&    r_some;
 
    test(some& in_some)
        : r_some(in_some)
    {
    }
};
 
 
int main()
{
    any a(some());
    printf("%d\n",*a.r_some.p);
}
 
int main_2()
{
    some s;
    any a(s);
    printf("%d\n",*a.r_some.p);
}

질문이라기에는 좀 그렇고....

클래스의 멤버 변수로 참조변수가 가능하지요....

일단 코드의 테스트는 VC2010에서 하였습니다...

사실 지금까지 다른 인스턴스를 참조하는 경우에 항상 포인터를 사용해왔습니다..

그러던중 포인터 대신에 참조변수를 통해서 다른 인스턴스를 참조해서 쓸수 있지 않을까 하다가 해보았더니 잘 되더군요...main_2 함수는 잘 동작합니다..

그러던중 포인터를 사용할때 흔히 발생하는 Dangerous Pointer 문제가 여기서도 발생하지 않을까 해서 위 예제를 작성해보았습니다..

역시나 이 main 함수에서 문제가 발생하더군요....

some의 인스턴스가 임시객체라서 라인 넘어가는 시점에 라이프사이클이 끝나서 소멸자가 호출됩니다..ㅠㅠ...

사실 임시객체라도 레퍼런스 전달이 일어나면 라이프 사이클이 레퍼런스하는놈보다 길어지지 않을까 생각했는데 그런일은 일어나지 않더군요....

그리고 나서 any의 인스턴스 a 를 통해서 참조인 멤버를 접근하면 Dangerous Pointer 가 되지요...사실 a.r_some 그 자체가 Dangerous Pointer라고는 좀 그렇고 Dangerous Reference 라고 해야 할까요?

이런 코딩 하면 안되겠지만 다른 분들은 클래스 멤버로서 다른 인스턴스의 참조를 쓰고 싶을땐 어떻게 하시나요? 역시나 포인터일까요? 아님 레퍼런스를 쓰시나요?

익명_사용자의 이미지

dangerous pointer란 용어는 생소하네요.

아마 dangling pointer를 말씀하신듯??
http://en.wikipedia.org/wiki/Dangling_pointer

 
Dangling pointers and wild pointers in computer programming are pointers that do not point to a valid object ... 

C/C++는 syntax-level에서의 reference-count와 같은 개념이 없기에
해당 객체의 life-cycle이 끝나면( 문법적으로 ) 어느 누가 reference하고 있던 말던 소멸자를 호출해야하는것이 당연하여 보입니다.

예를들어, 함수안에서 stack영역에 할당한 로컬 변수도, 누군가 레퍼런싱하고 있다고 해서
함수가 리턴된후에도 valid 해야하는건 non-sense입니다.

empty2fill의 이미지

스마트 포인터를 사용해보는 것은 어떠세요?

c++11이 사용가능하면 unique_ptr를 사용하거나

아니면 tr1 또는 boost 라이브러리의 shared_ptr, weak_ptr를 사용해 보세요.

——
———
Life is a tragedy when seen in close-up, but a comedy in long-shot. - Chaplin, Charlie -

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.