연결 목록이 노드 내부에 노드를 저장하는 대신 포인터를 사용하는 이유


121

Java에서 광범위하게 연결 목록을 사용했지만 C ++를 처음 접했습니다. 나는 프로젝트에서 나에게 주어진이 노드 클래스를 잘 사용하고 있었다.

class Node
{
  public:
   Node(int data);

   int m_data;
   Node *m_next;
};

하지만 대답이 잘되지 않은 질문이 하나있었습니다. 사용해야하는 이유

Node *m_next;

대신 목록의 다음 노드를 가리 킵니다.

Node m_next;

포인터 버전을 사용하는 것이 더 낫다는 것을 이해합니다. 나는 사실을 주장하지 않을 것이지만 그것이 왜 더 좋은지 모르겠습니다. 포인터가 메모리 할당에 어떻게 더 나은지에 대해 명확하지 않은 답변을 얻었으며 여기에있는 누군가가 나를 더 잘 이해하도록 도울 수 있는지 궁금합니다.


14
@self 실례? 왜 모든 것이 포인터 인 언어에는 연결 목록이 없습니까?
문헌 : Angew는 더 이상 자랑 SO의없는

41
객체 포인터 대 참조 측면에서 C 및 C ++가 Java와 어떻게 다른지 주목하는 것이 중요합니다. Node m_next노드에 대한 참조가 아니라 전체 Node자체에 대한 저장소입니다 .
Brian Cain

41
@self Java에는 명시 적으로 사용하지 않는 포인터가 있습니다.
m0meni

27
끝까지 내려 오는 거북이 는 선택 사항 이 아닙니다 . 광기는 어딘가에서 끝나야합니다.
WhozCraig 2015-04-09

26
Java에 대해 알고있는 모든 것을 잊어 버리십시오 . C ++와 Java는 근본적으로 다른 방식으로 메모리를 처리합니다. 책 추천에 대한이 질문을 보러 가서 하나를 선택하고 읽으십시오. 당신은 우리 모두에게 큰 호의를 베풀 것입니다.
Rob K

답변:


218

더 나은 것이 아니라 가능한 유일한 방법입니다.

Node 개체를 내부에 저장했다면 무엇 sizeof(Node)일까요? 그것은 것이 sizeof(int) + sizeof(Node)동일 할 것이다, sizeof(int) + (sizeof(int) + sizeof(Node))동일 할 것이다, sizeof(int) + (sizeof(int) + (sizeof(int) + sizeof(Node)))무한대 등.

그런 물체는 존재할 수 없습니다. 그건 불가능합니다 .


25
* 게으르게 평가되지 않는 한. 엄격한 평가가 아니라 무한 목록이 가능합니다.
Carcigenicate 2015

55
@Carcigenicate는 Node 객체의 일부 기능을 평가 / 실행하는 것이 아닙니다. 평가가 발생하기 전에 컴파일 타임에 결정되어야하는 Node의 모든 인스턴스의 메모리 레이아웃에 관한 것입니다.
Peteris 2015-04-09

6
@DavidK 이것을하는 것은 논리적으로 불가능합니다. 당신은 필요가 없습니다 여기에 포인터 (정말 잘 간접) - 당신에게서 숨길 수 있는지 언어를하지만 주위 결국, 방법.
Voo

2
@David 혼란 스러워요. 먼저 그것은 논리적으로 불가능하다는 데 동의하지만 그것을 고려하고 싶습니까? C 또는 C ++ 중 무엇이든 제거 하십시오. 내가 볼 수있는 한 당신이 꿈꾸는 어떤 언어로도 불가능 합니다. 그 구조는 정의에 따라 무한 재귀이며 어떤 수준의 간접적없이 우리는 그것을 깨뜨릴 수 없습니다.
Voo

13
@benjamin 나는 실제로 Haskell이 생성시 썽크를 할당했기 때문에 (다른 사람이 이것을 가져올 것이라는 것을 알았 기 때문에) 실제로 지적했습니다. 이것은 변장에 추가 데이터가있는 포인터
일뿐입니다

178

자바에서

Node m_node

다른 노드에 대한 포인터를 저장합니다. 당신은 그것에 대해 선택권이 없습니다. C ++에서

Node *m_node

같은 의미입니다. 차이점은 C ++에서는 객체에 대한 포인터가 아니라 실제로 객체를 저장할 수 있다는 것입니다. 그래서 포인터를 원한다고 말해야합니다. C ++에서 :

Node m_node

바로 여기에 노드를 저장하는 것을 의미합니다 (목록에서 작동 할 수 없음-결국 재귀 적으로 정의 된 구조로 끝남).


2
@SalmanA 나는 이미 이것을 알고 있었다. 나는 포인터가 없으면 왜 작동하지 않는지 알고 싶었습니다.
m0meni

3
@ AR7 둘 다 두 가지 다른 접근 방식으로 동일한 설명을 제공합니다. "일반"변수로 선언하면 생성자가 처음 호출 될 때 새 인스턴스로 인스턴스화됩니다. 그러나 인스턴스화가 완료되기 전에-첫 번째 생성자가 완료되기 전에-멤버 Node의 자체 생성자가 호출되어 또 다른 새 인스턴스를 인스턴스화합니다. 그리고 끝없는 의사 재귀를 얻습니다. 그것은 아니다 실제로 는 성능 문제이기 때문에, 너무 많은 완전히 엄격하고 문자 적 측면에서 크기 문제.
Panzercrisis 2015

그러나 실제로 원하는 것은 목록에서 다음 항목을 가리키는 방법 일뿐 입니다. Node실제로 첫 번째 Node. 따라서 기본적으로 Java가 객체를 처리하는 방식 인 포인터를 만듭니다. 메소드를 호출하거나 변수를 만들 때 Java는 객체의 사본이나 객체 자체를 저장하지 않습니다. 그것은 객체에 대한 참조를 저장하는데, 이것은 본질적으로 약간의 꼬마 장갑을 감싸고있는 포인터입니다. 이것은 두 답변이 본질적으로 말하는 것입니다.
Panzercrisis 2015

크기 나 속도 문제가 아니라 불가능한 문제입니다. 포함 된 Node 객체는 Node 객체를 포함하는 Node 객체를 포함합니다 ... 사실 그것을 컴파일하는 것은 불가능합니다
pm100

3
@Panzercrisis 둘 다 같은 설명을하고 있다는 것을 알고 있습니다. 그러나이 접근 방식은 내가 이미 이해하고있는 것, 즉 C ++에서 포인터가 작동하는 방식과 Java에서 포인터가 처리되는 방식에 중점을 두었 기 때문에 나에게 도움이되지 못했습니다. 허용 된 대답 은 크기를 계산할 수 없기 때문에 포인터를 사용하지 않는 이유 를 구체적으로 설명했습니다. 반면에 이것은 "재귀 적으로 정의 된 구조"로 더 모호하게 남겨졌습니다. 추신 : 당신이 방금 쓴 설명은 둘 다보다 더 잘 설명합니다 : D.
m0meni 2015

38

C ++는 Java가 아닙니다. 당신이 쓸 때

Node m_next;

Java에서는 작성과 동일합니다.

Node* m_next;

C ++에서. Java에서 포인터는 암시 적이며 C ++에서는 명시 적입니다. 쓰면

Node m_next;

C ++에서는 Node정의중인 객체 안에 인스턴스를 바로 넣습니다 . 항상 존재하며 생략 할 수 없으며 할당 new할 수없고 제거 할 수도 없습니다. 이 효과는 Java에서 달성 할 수 없으며 Java가 동일한 구문으로 수행하는 것과 완전히 다릅니다.


1
Java에서 비슷한 것을 얻으려면 수퍼 노드가 노드를 확장하는 경우 "확장"이 될 수 있습니다. 수퍼 노드는 노드의 모든 속성을 포함하고 모든 추가 공간을 예약해야합니다. 그래서 자바에서 당신은 "노드는 노드를 확장"할 수 없어
팔코

@Falco 사실, 상속은 기본 클래스를 제자리에 포함하는 형태입니다. 그러나 Java는 다중 상속을 허용하지 않기 때문에 (C ++와 달리) 상속을 통해 하나의 다른 기존 클래스의 인스턴스 만 가져올 수 있습니다. 그렇기 때문에 상속을 제자리 멤버 포함의 대체물로 생각하지 않습니다.
cmaster - 분석 재개 모니카

27

포인터를 사용하고 그렇지 않으면 코드를 사용합니다.

class Node
{
   //etc
   Node m_next; //non-pointer
};

... 것이 없습니다 컴파일러의 크기를 계산할 수 없기 때문에, 컴파일 Node. 이는 자체에 의존하기 때문입니다. 이는 컴파일러가 소비 할 메모리 양을 결정할 수 없음을 의미합니다.


5
더 나쁜 것은 유효한 크기가 존재하지 않는다는 것입니다. k == sizeof(Node)보유하고 유형에 데이터가있는 경우이를 보유한 sizeof(Node) = k + sizeof(Data) = sizeof(Node) + sizeof(Data)다음 sizeof(Node) > sizeof(Node).
bitmask

4
@bitmask 실수에 유효한 크기가 없습니다 . 무한을 허용하면 aleph_0작동합니다. (그냥 지나치게 현학적 인 :-))
k_g

2
@k_g 음, C / C ++ 표준은의 반환 값이 sizeof부호없는 정수 유형 임을 요구 하므로 초한 또는 실제 크기에 대한 희망이 있습니다. (더 현학적 인 것! : p)
Thomas

@Thomas : 자연 수도 있다고 지적 할 수도 있습니다. (Going over the -pedantic top : p)
bitmask

1
사실, Node이 코드 조각이 끝나기 전에 정의되지 않았으므로 실제로 내부에서 사용할 수 없습니다. 아직 선언되지 않은 클래스에 대한 포인터를 암시 적으로 포워드 선언하도록 허용하는 것은 항상 명시 적으로 포인터를 캐스팅 할 필요없이 이러한 구조를 가능하게하기 위해 언어에서 허용하는 약간의 속임수입니다.
osa

13

후자 ( Node m_next)는 노드 를 포함 해야합니다. 그것을 가리 키지 않을 것입니다. 그러면 요소가 연결되지 않습니다.


3
더 나쁜 것은 객체가 동일한 유형을 포함하는 것이 논리적으로 불가능하다는 것입니다.
Mike Seymour

노드 등을 포함하는 노드를 포함하는 노드이기 때문에 기술적으로 여전히 링크가 있지 않습니까?
m0meni

9
@ AR7 : 아니요, 봉쇄는 말 그대로 개체에 연결되지 않고 개체 내부에 있음을 의미합니다.
Mike Seymour

9

설명하는 접근 방식은 C ++뿐만 아니라 (대부분) 하위 집합 언어 C 와도 호환됩니다 . C 스타일 연결 목록을 개발하는 방법을 배우는 것은 저수준 프로그래밍 기술 (예 : 수동 메모리 관리)을 소개하는 좋은 방법이지만 일반적으로 최신 C ++ 개발을위한 최선의 방법 은 아닙니다 .

아래에서는 C ++에서 항목 목록을 관리하는 방법에 대해 네 가지 변형을 구현했습니다.

  1. raw_pointer_demo당신과 동일한 접근 방식을 사용합니다-원시 포인터 사용에 필요한 수동 메모리 관리. 여기서 C ++의 사용은 syntactic-sugar 에만 해당되며 사용 된 접근 방식은 C 언어와 호환됩니다.
  2. 에서 shared_pointer_demo목록 관리는 여전히 수동으로 수행되지만, 메모리 관리는 자동 (원시 포인터를 사용하지 않습니다). 이것은 아마도 Java에서 경험 한 것과 매우 유사합니다.
  3. std_list_demo표준 라이브러리 list컨테이너를 사용합니다 . 이것은 자신의 라이브러리를 롤링하지 않고 기존 라이브러리에 의존하는 경우 얼마나 쉽게 얻을 수 있는지 보여줍니다.
  4. std_vector_demo표준 라이브러리 vector컨테이너를 사용합니다 . 이것은 단일 연속 메모리 할당에서 목록 저장소를 관리합니다. 즉, 개별 요소에 대한 포인터가 없습니다. 다소 극단적 인 경우에는 상당히 비효율적 일 수 있습니다. 그러나 일반적인 경우에는 이것이 C ++의 목록 관리에 권장되는 모범 사례입니다 .

참고 :이 모든 것 중에서 raw_pointer_demo실제로 "누수"메모리를 피하기 위해 목록을 명시 적으로 삭제해야합니다. 다른 세 가지 방법은 컨테이너가 범위를 벗어날 때 (함수 종료시) 목록과 그 내용을 자동으로 파괴합니다. 요점은 : C ++는 이와 관련하여 매우 "자바와 유사"할 수 있지만, 고수준 도구를 사용하여 프로그램을 개발하기로 선택한 경우에만 가능합니다.


/*BINFMTCXX: -Wall -Werror -std=c++11
*/

#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <memory>
using std::cerr;

/** Brief   Create a list, show it, then destroy it */
void raw_pointer_demo()
{
    cerr << "\n" << "raw_pointer_demo()..." << "\n";

    struct Node
    {
        Node(int data, Node *next) : data(data), next(next) {}
        int data;
        Node *next;
    };

    Node * items = 0;
    items = new Node(1,items);
    items = new Node(7,items);
    items = new Node(3,items);
    items = new Node(9,items);

    for (Node *i = items; i != 0; i = i->next)
        cerr << (i==items?"":", ") << i->data;
    cerr << "\n";

    // Erase the entire list
    while (items) {
        Node *temp = items;
        items = items->next;
        delete temp;
    }
}

raw_pointer_demo()...
9, 3, 7, 1

/** Brief   Create a list, show it, then destroy it */
void shared_pointer_demo()
{
    cerr << "\n" << "shared_pointer_demo()..." << "\n";

    struct Node; // Forward declaration of 'Node' required for typedef
    typedef std::shared_ptr<Node> Node_reference;

    struct Node
    {
        Node(int data, std::shared_ptr<Node> next ) : data(data), next(next) {}
        int data;
        Node_reference next;
    };

    Node_reference items = 0;
    items.reset( new Node(1,items) );
    items.reset( new Node(7,items) );
    items.reset( new Node(3,items) );
    items.reset( new Node(9,items) );

    for (Node_reference i = items; i != 0; i = i->next)
        cerr << (i==items?"":", ") << i->data;
    cerr<<"\n";

    // Erase the entire list
    while (items)
        items = items->next;
}

shared_pointer_demo()...
9, 3, 7, 1

/** Brief   Show the contents of a standard container */
template< typename C >
void show(std::string const & msg, C const & container)
{
    cerr << msg;
    bool first = true;
    for ( int i : container )
        cerr << (first?" ":", ") << i, first = false;
    cerr<<"\n";
}

/** Brief  Create a list, manipulate it, then destroy it */
void std_list_demo()
{
    cerr << "\n" << "std_list_demo()..." << "\n";

    // Initial list of integers
    std::list<int> items = { 9, 3, 7, 1 };
    show( "A: ", items );

    // Insert '8' before '3'
    items.insert(std::find( items.begin(), items.end(), 3), 8);
    show("B: ", items);

    // Sort the list
    items.sort();
    show( "C: ", items);

    // Erase '7'
    items.erase(std::find(items.begin(), items.end(), 7));
    show("D: ", items);

    // Erase the entire list
    items.clear();
    show("E: ", items);
}

std_list_demo()...
A:  9, 3, 7, 1
B:  9, 8, 3, 7, 1
C:  1, 3, 7, 8, 9
D:  1, 3, 8, 9
E:

/** brief  Create a list, manipulate it, then destroy it */
void std_vector_demo()
{
    cerr << "\n" << "std_vector_demo()..." << "\n";

    // Initial list of integers
    std::vector<int> items = { 9, 3, 7, 1 };
    show( "A: ", items );

    // Insert '8' before '3'
    items.insert(std::find(items.begin(), items.end(), 3), 8);
    show( "B: ", items );

    // Sort the list
    sort(items.begin(), items.end());
    show("C: ", items);

    // Erase '7'
    items.erase( std::find( items.begin(), items.end(), 7 ) );
    show("D: ", items);

    // Erase the entire list
    items.clear();
    show("E: ", items);
}

std_vector_demo()...
A:  9, 3, 7, 1
B:  9, 8, 3, 7, 1
C:  1, 3, 7, 8, 9
D:  1, 3, 8, 9
E:

int main()
{
    raw_pointer_demo();
    shared_pointer_demo();
    std_list_demo();
    std_vector_demo();
}

Node_reference위 의 선언은 Java와 C ++ 간의 가장 흥미로운 언어 수준 차이 중 하나를 다룹니다. Java에서 유형의 객체를 선언하면 Node별도로 할당 된 객체에 대한 참조가 암시 적으로 사용됩니다. C ++에서는 참조 (포인터) 할당과 직접 (스택) 할당을 선택할 수 있으므로 구별을 명시 적으로 처리해야합니다. 대부분의 경우 직접 할당을 사용하지만 목록 요소에는 사용하지 않습니다.
Brent Bradburn

std :: deque 의 가능성도 권장하지 않은 이유를 모르겠습니다 .
Brent Bradburn

8

개요

C ++에서는 객체를 참조하고 할당하는 두 가지 방법이 있지만 Java에는 한 가지 방법 만 있습니다.

이를 설명하기 위해 다음 다이어그램은 객체가 메모리에 저장되는 방식을 보여줍니다.

1.1 포인터가없는 C ++ 항목

class AddressClass
{
  public:
    int      Code;
    char[50] Street;
    char[10] Number;
    char[50] POBox;
    char[50] City;
    char[50] State;
    char[50] Country;
};

class CustomerClass
{
  public:
    int          Code;
    char[50]     FirstName;
    char[50]     LastName;
    // "Address" IS NOT A pointer !!!
    AddressClass Address;
};

int main(...)
{
   CustomerClass MyCustomer();
     MyCustomer.Code = 1;
     strcpy(MyCustomer.FirstName, "John");
     strcpy(MyCustomer.LastName, "Doe");
     MyCustomer.Address.Code = 2;
     strcpy(MyCustomer.Address.Street, "Blue River");
     strcpy(MyCustomer.Address.Number, "2231 A");

   return 0;
} // int main (...)

.......................................
..+---------------------------------+..
..|          AddressClass           |..
..+---------------------------------+..
..| [+] int:      Code              |..
..| [+] char[50]: Street            |..
..| [+] char[10]: Number            |..
..| [+] char[50]: POBox             |..
..| [+] char[50]: City              |..
..| [+] char[50]: State             |..
..| [+] char[50]: Country           |..
..+---------------------------------+..
.......................................
..+---------------------------------+..
..|          CustomerClass          |..
..+---------------------------------+..
..| [+] int:      Code              |..
..| [+] char[50]: FirstName         |..
..| [+] char[50]: LastName          |..
..+---------------------------------+..
..| [+] AddressClass: Address       |..
..| +-----------------------------+ |..
..| | [+] int:      Code          | |..
..| | [+] char[50]: Street        | |..
..| | [+] char[10]: Number        | |..
..| | [+] char[50]: POBox         | |..
..| | [+] char[50]: City          | |..
..| | [+] char[50]: State         | |..
..| | [+] char[50]: Country       | |..
..| +-----------------------------+ |..
..+---------------------------------+..
.......................................

경고 :이 예제에서 사용 된 C ++ 구문은 Java의 구문과 유사합니다. 그러나 메모리 할당은 다릅니다.

1.2 포인터를 사용하는 C ++ 항목

class AddressClass
{
  public:
    int      Code;
    char[50] Street;
    char[10] Number;
    char[50] POBox;
    char[50] City;
    char[50] State;
    char[50] Country;
};

class CustomerClass
{
  public:
    int           Code;
    char[50]      FirstName;
    char[50]      LastName;
    // "Address" IS A pointer !!!
    AddressClass* Address;
};

.......................................
..+-----------------------------+......
..|        AddressClass         +<--+..
..+-----------------------------+...|..
..| [+] int:      Code          |...|..
..| [+] char[50]: Street        |...|..
..| [+] char[10]: Number        |...|..
..| [+] char[50]: POBox         |...|..
..| [+] char[50]: City          |...|..
..| [+] char[50]: State         |...|..
..| [+] char[50]: Country       |...|..
..+-----------------------------+...|..
....................................|..
..+-----------------------------+...|..
..|         CustomerClass       |...|..
..+-----------------------------+...|..
..| [+] int:      Code          |...|..
..| [+] char[50]: FirstName     |...|..
..| [+] char[50]: LastName      |...|..
..| [+] AddressClass*: Address  +---+..
..+-----------------------------+......
.......................................

int main(...)
{
   CustomerClass* MyCustomer = new CustomerClass();
     MyCustomer->Code = 1;
     strcpy(MyCustomer->FirstName, "John");
     strcpy(MyCustomer->LastName, "Doe");

     AddressClass* MyCustomer->Address = new AddressClass();
     MyCustomer->Address->Code = 2;
     strcpy(MyCustomer->Address->Street, "Blue River");
     strcpy(MyCustomer->Address->Number, "2231 A");

     free MyCustomer->Address();
     free MyCustomer();

   return 0;
} // int main (...)

두 방법의 차이점을 확인하면 첫 번째 방법에서는 주소 항목이 고객 내에 할당되고 두 번째 방법에서는 각 주소를 명시 적으로 만들어야한다는 것을 알 수 있습니다.

경고 : Java는이 두 번째 기술과 같이 메모리에 개체를 할당하지만 구문은 첫 번째 방법과 같으므로 "C ++"를 처음 접하는 사람들에게 혼동을 줄 수 있습니다.

이행

따라서 목록 예제는 다음 예제와 유사 할 수 있습니다.

class Node
{
  public:
   Node(int data);

   int m_data;
   Node *m_next;
};

.......................................
..+-----------------------------+......
..|            Node             |......
..+-----------------------------+......
..| [+] int:           m_data   |......
..| [+] Node*:         m_next   +---+..
..+-----------------------------+...|..
....................................|..
..+-----------------------------+...|..
..|            Node             +<--+..
..+-----------------------------+......
..| [+] int:           m_data   |......
..| [+] Node*:         m_next   +---+..
..+-----------------------------+...|..
....................................|..
..+-----------------------------+...|..
..|            Node             +<--+..
..+-----------------------------+......
..| [+] int:           m_data   |......
..| [+] Node*:         m_next   +---+..
..+-----------------------------+...|..
....................................v..
...................................[X].
.......................................

요약

연결된 목록에는 가변 수량의 항목이 있으므로 메모리는 필요에 따라 사용 가능한대로 할당됩니다.

최신 정보:

@haccks가 그의 게시물에서 언급했듯이 언급 할 가치가 있습니다.

때때로 참조 또는 개체 포인터는 중첩 된 항목 ( "UML 구성"이라고도 함)을 나타냅니다.

때로는 참조 또는 개체 포인터가 외부 항목 ( "UML 집계"라고도 함)을 나타냅니다.

그러나 같은 클래스의 중첩 된 항목은 "no-pointer"기술로 적용 할 수 없습니다.


7

참고로, 클래스 또는 구조체의 첫 번째 멤버가 다음 포인터 인 경우 (따라서 가상 함수 나 다음을 의미하는 클래스의 다른 기능이 클래스 또는 구조체의 첫 번째 멤버가 아님), 다음 포인터만으로 "기본"클래스 또는 구조를 사용할 수 있으며 추가, 이전 삽입, 앞에서 검색 등과 같은 기본 연결 목록 작업에 공통 코드를 사용할 수 있습니다. 이는 C / C ++가 클래스 또는 구조의 첫 번째 멤버 주소가 클래스 또는 구조의 주소와 동일 함을 보장하기 때문입니다. 기본 노드 클래스 또는 구조체에는 기본 연결 목록 함수에서 사용할 다음 포인터 만있을 것입니다. 그러면 필요에 따라 기본 노드 유형과 "파생 된"노드 유형간에 변환하는 데 유형 변환이 사용됩니다. 참고 사항-C ++에서 기본 노드 클래스에 다음 포인터 만있는 경우


6

연결 목록에서 포인터를 사용하는 것이 더 좋은 이유는 무엇입니까?

그 이유는 Node객체 를 만들 때 컴파일러가 해당 객체에 메모리를 할당해야하고 객체 크기가 계산되기 때문입니다.
모든 유형에 대한 포인터의 크기는 컴파일러에 알려져 있으므로 객체의 자체 참조 포인터 크기를 계산할 수 있습니다.

Node m_node대신 사용 되면 컴파일러는의 크기에 대해 알지 못하며 계산 Node무한 재귀 에 갇히게 됩니다 sizeof(Node). 항상 기억하세요 : 클래스는 자체 유형의 멤버를 포함 할 수 없습니다 .


5

이것은 C ++에서

int main (..)
{
    MyClass myObject;

    // or

    MyClass * myObjectPointer = new MyClass();

    ..
}

Java 에서 이와 동일합니다.

public static void main (..)
{
    MyClass myObjectReference = new MyClass();
}

둘 다 MyClass기본 생성자 를 사용 하는 새 개체를 만듭니다 .


0

연결된 목록이 노드 내부에 노드를 저장하는 대신 포인터를 사용하는 이유는 무엇입니까?

물론 사소한 대답이 있습니다.

포인터로 한 노드를 다음 노드에 연결 하지 않으면 연결된 목록 이 아닙니다 .

연결 목록이 존재하는 이유는 개체를 함께 연결할 수 있기를 원하기 때문입니다. 예를 들어, 우리는 이미 어딘가에서 물건을 가지고 있습니다. 예를 들어, 이제 실제 객체 (복사본이 아님)를 대기열 끝에 놓으려고합니다. 이미 큐에있는 마지막 요소 의 링크 를 추가하는 항목에 추가하면됩니다. 기계 용어로는 다음 요소의 주소로 단어를 채우는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.