2010-01-30 5 views
6

저는 C++에서 포인터에 대해 배우기 시작했습니다. 포인터를 사용할시기와 실제 객체를 사용해야하는 시점에 대해서는 잘 모르겠습니다.C++에서 포인터를 사용하는 경우

예를 들어, 과제 중 하나에서 gPolyline 클래스를 구성해야합니다. 여기서 각 포인트는 gVector에 의해 정의됩니다. 지금 gPolyline 클래스 내 변수는 다음과 같습니다

private: 
vector<gVector3*> points; 

나는> 대신 포인트, 그것은 어떤 차이를 만들 것 < gVector3을 벡터가 있다면? 또한, 포인터를 사용할시기에 대한 일반적인 경험 법칙이 있습니까? 미리 감사드립니다!

+0

메모리 복사가 가장 큰 영향은 다음과 같습니다 유형 T가 작도 기본되지 않은 경우, C++ 표준에서 요구하지 않는 것, 그 다음 사용자는 내가 아래에 설명하려고 잠재적 인 문제를 알고 있어야합니다. 당신이 3 개의 ints에 대해서 이야기한다면 무시할 만하다. – pestilence669

+2

@ mloskot - 앨리스가 네 가지 질문 만하고 다른 세 가지 대답을 수락 한 것을 보았을 것입니다. 그래서 그녀는 SO가 어떻게 작동하는지 분명히 알고 있으며 아마 그녀의 질문에 가장 잘 대답하는 답을 평가할 것입니다. – ChrisF

+1

@Neil & @ChrisF - 어떤 요구 사항이있는 것은 아닙니다. 1 ~ 2 시간 이상 기다리는 것이 옳습니다. 앨리스에게 감사하십시오. – mloskot

답변

2

필요하면 포인터를 사용하고 가능한 경우 값 또는 참조를 사용하는 것이 일반적입니다.

vector<gVector3> 삽입 요소를 사용하면 이러한 요소의 사본이 만들어지고 요소는 더 이상 삽입 한 항목에 연결되지 않습니다. 포인터를 저장할 때 벡터는 삽입 한 객체를 참조합니다.

여러 벡터가 동일한 요소를 공유하도록하여 요소의 변경 사항이 모든 벡터에 반영되도록하려면 포인터가 포함될 벡터가 필요합니다. 그러한 기능을 필요로하지 않으면 일반적으로 값을 저장하는 것이 더 좋습니다. 예를 들어 이러한 모든 지적 된 객체를 삭제할 때 걱정할 필요가 없습니다.

0

포인터 나 개체를 사용할 수 있습니다. 실제로는 끝날 때와 같습니다.

포인터가있는 경우 실제 개체의 공간을 할당 한 다음 포인터를 가리켜 야합니다. 하루가 끝날 무렵 포인터 또는 객체 자체를 저장하는지 여부에 관계없이 백만 개의 객체가있는 경우 메모리에 백만 개의 객체가 할당되는 공간이 생깁니다.

언제 대신 포인터를 사용할 수 있습니까? 객체 자체를 전달해야하는 경우 개별 요소는 데이터 구조에 포함 된 후에도 매번 검색하지 않고도 수정하거나 사용자 정의 메모리 관리자를 사용하여 할당, 할당 해제 및 정리를 관리 할 수 ​​있습니다. 개체.

개체를 STL 구조에 넣는 것이 더 쉽고 간단합니다. 이해하기 어려울 수있는 * 및 -> 연산자가 더 적게 필요합니다. 특정 STL 객체는 객체 대신 객체 자체를 기본 형식 (즉, 항목을 해시해야하는 해시 테이블 - 포인터를 가리키는 것이 아니라 객체를 해시 할 필요가 있음)의 포인터 대신 표시해야하지만, 재정의 함수 등

결론 : 의미가있는 경우 포인터를 사용하십시오. 그렇지 않으면 개체를 사용하십시오.

+0

여기 포인터를 사용하는 것도 좋은 생각이 아닙니다. STL의 반복자를 사용하고 컬렉션을 반복하는 것이 더 좋습니다. 오브젝트 공간이 걱정된다면, 어떤 형태의'shared_ptr'을 사용하는 것이 더 낫습니다. 마지막으로, 원시 포인터를 사용하면'std :: remove','std :: remove_if','std :: unique','std :: replace','std :: remove'와 같은 제거 의미론을 가진 모든 표준 알고리즘을 깨뜨린다. replace_if' 등등. –

1

포인터는 일반적으로 최신 C++에서는 피해야합니다. 포인터의 주된 목적은 요즘 포인터가 다형성을 가질 수 있다는 사실에 초점을두고 있습니다. 반면 명시 적 객체는 그렇지 않습니다.

std::shared_ptr (컴파일러가 C++ 0x 확장을 지원하는 경우), std::tr1::shared_ptr (컴파일러가 C++ 0x를 지원하지 않는 경우와 같이 스마트 포인터 클래스를 사용하는 것이 좋지만 요즘에는 다형성이 필요할 때 그렇습니다. TR1 지원) 또는 boost::shared_ptr.

+0

"modern C++"이 무슨 뜻인지 모르겠지만 많은 거대한 프로젝트에서 나는'STL_Struct '에서'STL_Struct '로 코드를 옮겨야 만했다. :) 때때로 위의 대답에서 명확히 설명하는 이유 때문에 개체 자체 대신 개체에 대한 포인터가 필요합니다. 그러나 포인터를 사용할 필요는 없습니다. –

+0

"Modern C++"은 C++ 03 표준 또는 ANSI/ISO 표준화 C++를 의미합니다. 여러 구형 컴파일러는 표준을 완벽하게 구현하지 못하고 컴파일러의 불일치를 패치하기위한 포인터가 필요합니다. –

+0

@Neil - Fixed - 또한 귀하의 이름을 고정 ... –

0

일반적으로 개체를 사용합니다.
막대기에 사과보다 사과를 먹기가 더 쉽습니다 (2 미터 막대기가 좋기 때문에 캔디 사과를 좋아하기 때문에). 당신이 당신이 동적으로 (new 연산자를 사용) g3Vector의 새로운 객체를 할당하는 것을 의미한다 벡터 < g3Vector * >이 있다면이 경우

그냥 벡터 <gVector3>

합니다. 그렇다면 어떤 시점에서 이러한 포인터에 delete를 호출해야합니다. std :: Vector는 그렇게하도록 설계되지 않았습니다.

그러나 모든 규칙은 예외입니다.

g3Vector가 복사하는 데 드는 비용이 많이 드는 거대한 개체 인 경우 (설명서를 읽는 데 어려움이 있음) 포인터로 저장하는 것이 더 효율적일 수 있습니다.그러나이 경우 boost :: ptr_vector를 사용합니다. <g3Vector> 이것은 객체의 수명을 자동으로 관리하기 때문에.

+0

@Billy : boost :: ptr_vector에 대해 읽어보십시오. –

+0

죄송합니다 - 해당 댓글은 다른 게시물 용입니다. –

1

일반적으로 가능한 경우 포인터를 사용하는 것이 좋습니다.하지만 참조 또는 다른 방법으로 개체 개체 (값 생각)를 사용하는 것이 좋습니다.

우선 gVector3이 표준 컨테이너의 요구 사항을 충족하는지, 즉 유형 gVector3이 복사 및 할당 가능한지 알아야합니다. gVector3도 기본 구성 가능하면 유용합니다 (아래의 UPDATE 참고 참조). 는 않습니다 가정하면, 다음 std::vector

std::vector<gVector3> points; 
points.push_back(gVector(1, 2, 3)); // std::vector will make a copy of passed object 

에 직접 gVector3의 저장소 개체를 두 가지 선택 또는 수동으로 gVector3 객체의 생성 (및 파괴)를 관리 할 수 ​​있습니다.

std :: vector points; points.push_back (새 gVector3 (1, 2, 3)); // ...

points 어레이가 더 이상 필요하지 않은 경우 모든 요소를 ​​말하고 그에 대해 delete 연산자를 호출해야합니다.

gVector3을 개체로 조작 할 수있는 경우 (값 또는 값 개체로 생각할 수 있음) 복사 생성자 및 할당 연산자의 가용성 덕분에 (위 조건을 참조하십시오) 다음 작업

gVector3 v1(1, 2, 3); 
gVector3 v2; 
v2 = v1; // assignment 
gVector3 v3(v2); // copy construction 

또는 당신이 원하는 또는 new 연산자를 사용 동적 저장gVector3의 객체를 할당해야 할 수도 있습니다 가능합니다. 의미, 당신은 원하거나 자신의 개체의 수명을 관리해야 할 수도 있습니다. 그런데

은 또한 When should I use references, and when should I use pointers?

UPDATE 궁금 수 있습니다 : 여기 기본 constructibility에 노트에 설명이다. Neil이 초기에는 불분명하다고 지적하여 주신 데 대해 감사드립니다. Neil이 올바르게 알아 차렸으므로 C++ 표준에서는 필요하지 않지만이 기능은 중요하고 유용하기 때문에이 기능을 지적했습니다.

#include <vector> 
struct T 
{ 
    int i; 
    T(int i) : i(i) {} 
}; 
int main() 
{ 
    // Request vector of 10 elements 
    std::vector<T> v(10); // Compilation error about missing T::T() function/ctor 
} 
+1

당신은 복사 가능하고 할당 가능한 요구 사항에 대해 옳습니다 - 당신은 기본 구성 가능에 대해 틀렸습니다 - 그러한 요구 사항은 없습니다. –

+0

+1 매우 좋은 점. 더 명확하게 답변을 업데이트했습니다. 감사! – mloskot

+0

다음과 같이 말할 수 있습니다 : std :: vector v (10, T (0)); 또한이 실수를 저질렀습니다. http://punchlet.wordpress.com/2009/12/03/letter-the-third의 기본 생성자에서 내 블로그 항목을 볼 수 있습니다. –

관련 문제