2013-10-25 3 views
2

저는 C++에서 참조 멤버의 사용 사례 하나를 찾아 낼 수 없다는 것을 깨달았습니다. 다음 클래스를 정의하면 다음과 같습니다.참조 회원을 언제 사용합니까?

class Book { 
    public: 
     Book(const Author& author) : author(author) {} 
    private: 
     const Author &author; 
} 

어떻게 사용할 수 있습니까? 나는 그것에 new 에드 Author을 전달하는 경우 :

Book book(*(new Author())); 

은 메모리를 누설하지 않습니다? Author은 언제 출시 되나요?

다시 시도하겠습니다. 로컬 변수를 전달하는 방법 :

반환 된 책에 유효하지 않은 (릴리스 된) 참조가 없습니까?

세 번째 사용 방법은 상상할 수 없습니다. 그렇다면 레퍼런스 멤버는 왜 존재합니까? 언제 사용해야합니까?

편집 : 나는 share_ptr이 있음을 알고 있습니다. 그러나 나는 언제나 참고로 share_ptr을 선호해야합니까?

+0

개체를 할당 한 방법에 관계없이 참조를 초기화 할 수 있습니다 (개체가 참조를 보유한 개체의 인스턴스보다 수명이 길어질 수 있음). – thokra

답변

3

작성자의 유효 기간이 책의 길이와 같거나 적어도 작성자의 평생 이외의 시간에 책의 참고 사항을 사용하지 않도록주의해야합니다. 경우, 첫 번째 메모리 누수 (또는 것 : 당신이 말하는 것처럼

Author author; 
Book book(author); 

이 질문의 예제 모두 나쁜 : 다음 사항을 확인하는 간단한 방법은 저자가 처음 생성과 같은 범위에 넣어하는 것입니다 컴파일하기 위해 *을 추가했습니다.) 그리고 두 번째는 매달린 참조를 남깁니다. 그러나 객체 수명을 관리하는 다른 많은 방법이 있습니다.

2

함수가 const Author&을 필요로하고 당신이 new Author()을 전달하면 new Author()Author* 아닌 Author& 때문에, 당신의 프로그램이 컴파일되지 않습니다.

*(new Author())을 전달할 수 있지만 Book의 소멸자가 &author을 삭제하지 않는 한 유출됩니다. 그러나, 참조 멤버를 갖는 것은 매우 이상하며 소멸자는 해당 멤버의 주소와 delete을 가져 오는 것이 매우 이상합니다. 동료 개발자는 함수 서명에서 명확하지 않기 때문에 특히 인수가 new을 사용하여 할당되어야한다는 점에서 당신을 싫어할 것입니다.

AuthorBook(const Author& author)으로 전달할 수 있지만 Author은 적어도 Book만큼 길어야합니다. 그래, 코드에서

반환 된 책의 참조가 잘못되었습니다.

null 포인터가있는 것과 같은 이유 때문에 참조 멤버가 있다고 의심됩니다. 구현하기가 쉽기 때문입니다.

1

일반적으로 참조 값은 객체를 값으로 복사하는 것이 비용이 많이 드는 경우에 유용합니다. 인수로 함수에 객체를 전달하고 복사하는 데 비용이 많이 든다면 참조를 사용하는 것이 좋습니다.당신이 기능에 의해 수정 객체를 의미하지 않는 경우 당연히, 당신은 실제로 일정 참조 사용할 것이다

void someFunc(const BigObject& object) 
{ 
    /* 'object' is used here */ 
} 

이제 클래스 생성자는 "또 다른 기능을"입니다, 그래서 우리는 사용할 수 있습니다 같은 패턴 : 여기에의 수명 동안 을 사용하기 위해 일부 클래스 인스턴스에 복사하는 데 비용이 많이 드는 개체를 제공하려는 경우 해당 클래스에서 제공된 개체에 바인딩 될 const-ref 멤버를 정의하는 것이 의미가 있습니다. 클래스 생성자 :

class Worker 
{ 
public: 
    Worker(const BigObject& object) : m_object(object) { /* ... */ } 
    // ... 
private: 
    const BigObject& m_object; 
} 

BigObject object; 
Worker worker(object); 

냇 요컨대, 여기서 유의해야 할 가장 중요한 점은 BigObject 객체 이 객체가 존재하는 동안이 파괴되지 않도록해야한다는 것입니다. (위의 예제에서는 두 변수가 모두 자동이기 때문에 OK입니다.)

동일한 효과를 얻으려면 참조 대신 포인터를 사용할 수 있지만 포인터를 사용하면 포인터를 사용할 때 항상 생각해야합니다 0 (의도적 또는 우발적)이며 객체를 전달하는 데 명시 적으로 & 연산자를 사용해야하므로 참조 버전은 코드를 단순하게 만듭니다.