2010-02-22 4 views
6

이 문제는 상당히 오래 지속되고 있습니다. 고정 된 크기의 2D 배열을 클래스 멤버로 보유하고 있습니다.2D 배열에 대한 포인터 전달 C++

class myClass 
{ 
public: 
     void getpointeM(...??????...); 
     double * retpointM(); 

private: 

    double M[3][3]; 

}; 

int main() 
{ 
    myClass moo; 
    double *A[3][3]; 

    moo.getpointM(A); ??? 
    A = moo.retpointM(); ??? 

} 

외부에 M 행렬에 대한 포인터를 전달하고 싶습니다. 아마도 매우 간단 할 것이지만 &* 등의 적절한 조합을 찾을 수 없습니다.

도움 주셔서 감사합니다. 당신이 정말로 사소에서 직접 다른 2 차원 배열에 double *를 켤 수 없습니다, 그러나 클래스 외부

public: 
    double * getMatrix() { return &M[0][0]; } 

:

답변

9

double *A[3][3];double *s의 2 차원 배열입니다. 너는 double (*A)[3][3]; 을 원한다.

그런 다음 A*A 및 은 모두 주소가 같고 형식이 다릅니다.

일을 단순화 할 수있는 형식 정의를 만드는 것은 :

typedef double d3x3[3][3]; 

이 존재의 C++, 당신은 참조로 변수를 전달해야합니다, 포인터하지 : 이제

void getpointeM(d3x3 &matrix); 

당신이 괄호를 사용할 필요가 없습니다 그리고 컴파일러는 올바른 크기의 배열을 전달하는지 확인합니다. 당신의 main() 기능에

+0

"this is C++"또는 "할 수 있기 때문에"라는 참조를 사용하지 마십시오. 사용 가능한 대안보다 명확한 경우 사용하십시오. –

+0

@ 로거 : 네, 글쎄요, 어쨌든 여기에 적당합니다 : v) – Potatoswatter

0

짧은 대답은 배열의 시작에 double *를 얻을 수 있다는 것입니다 적어도 내가 본 것 같은 패턴은 아닙니다.

주 (double A [3] [3])에서 2D 배열을 만들고 으로 전달하여 getPoint 메소드에 전달하면 전달 된 배열에 값을 복사 할 수 있습니다. 그러면 원래의 수정 가능한 데이터가 아닌 원하는 복사본을 얻을 수 있습니다. 단점은 물론 복사해야한다는 것입니다.

+0

아니요! 포기하지 마라. – Potatoswatter

0

:

double *A[3][3]; 

는 (더블 또는 포인터)는 3 × 3 double*의 배열을 만듭니다. 즉, 9 x 32 비트의 인접한 메모리 워드가 9 개의 메모리 포인터를 저장합니다.

이 배열의 복사본main()에 만들 필요가 없습니다. 클래스가 삭제되고이 정보에 계속 액세스하려는 경우가 아닙니다. 대신이 멤버 배열의 시작 부분에 대한 포인터를 반환 할 수 있습니다.당신은 기능과 당신이 포인터를 전달하는 경우,

double *A; 

그러나 :

만 내부 클래스 멤버에 대한 포인터를 반환 할 경우

, 당신은 정말 main()의 단일 포인터 값이 필요합니다 그 값을 업데이트하는 기능이 필요합니다, 당신은 함수가 호출로 다시 실제 포인터 값을 반환 할 수 있도록 이중 포인터를 (필요

double **A; 

그리고내부 0 당신은 단순히 내부 구성원 (M)에 가리킬 수 있습니다 :

getpointeM(double** A) 
{ 
    // Updated types to make the assignment compatible 
    // This code will make the return argument (A) point to the 
    // memory location (&) of the start of the 2-dimensional array 
    // (M[0][0]). 
    *A = &(M[0][0]); 
} 
+0

글쎄 그것은 정말로하고 싶었던 것처럼 보입니다 :)하지만 여전히 오류가 있습니다 : 'double [3] [3]'을 과제에 'double *'을 입력하십시오. – Moomin

+0

죄송합니다. 실수를 저지르십시오. ** 두 줄에 **을 추가하는 것을 잊어 버렸습니다. – Moomin

+2

이것은 나에게 전혀 이해가되지 않습니다. 멤버는 double M [3] [3]으로 선언됩니다. '* A = M'은 왼쪽이'double *'이고 오른쪽이'double (*) [3] '이므로 컴파일되지 않을 것입니다. 이러한 유형은 호환되지 않습니다. – AnT

0
class myClass 
{ 
public: 
     void getpointeM(double *A[3][3]) 
     { 
      //Initialize array here 
     } 

private: 

    double M[3][3]; 

}; 

int main() 
{ 
    myClass moo; 
    double *A[3][3]; 

    moo.getpointM(A); 
} 
3

귀하의 의도는 명확하지 않다. getpointeM은 무엇을해야하나요? 매개 변수를 통해 내부 행렬에 대한 포인터를 반환하거나 행렬의 복사본을 반환합니까?

포인터를 반환하려면, 당신은

... 
double (*retpointM())[3][3] { return &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    A = moo.retpointM(); 
} 

이 비록 읽기도 어렵다 다음과 같이이

// Pointer-based version 
... 
void getpointeM(double (**p)[3][3]) { *p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(&A); 
} 

// Reference-based version 
... 
void getpointeM(double (*&p)[3][3]) { p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(A); 
} 

retpointM에 대한 선언이 보일 것이다 할 수 있습니다. 당신은 당신의 코드를 수행 할 수 있습니다 위의 예

// Pointer-based version 
... 
void getpointeM(M3x3 **p) { *p = &M; } 
... 
int main() { 
    M3x3 *A; 
    moo.getpointM(&A); 
} 

// Reference-based version 
... 
void getpointeM(M3x3 *&p) { p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(A); 
} 

// retpointM 
... 
M3x3 *retpointM() { return &M; } 
... 
int main() { 
    M3x3 *A; 
    A = moo.retpointM(); 
} 
0

로 변환됩니다이 경우 배열 유형

typedef double M3x3[3][3]; 

에 대한 형식 정의 이름을 사용하는 경우가 많은 명확하게 볼 수 있습니다 double 배열로 작업하는 주요 함수를 myClass에 멤버 함수로 옮겨 놓습니다. 해당 2D 배열에 대한 포인터를 전달하는 어려움을 처리 할 필요가 없을뿐만 아니라 클래스 외부의 코드는 클래스가 A를 구현하는 방법에 대한 세부 정보를 더 이상 알 필요가 없습니다. myClass를 사용하여 작업을 수행하게합니다. 예를 들어 A의 가변 크기를 허용하고 vectorvector 일 때 배열을 대체하기로 결정했다면 호출 코드를 다시 작성하지 않아도됩니다.

0

비공개 대신 M을 공개로 설정하십시오. 포인터를 통해 M에 액세스 할 수 있기를 원하므로 M은 캡슐화되지 않습니다.

struct myClass { 
    myClass() { 
    std::fill_n(&M[0][0], sizeof M/sizeof M[0][0], 0.0); 
    } 
    double M[3][3]; 
}; 

int main() { 
    myClass moo; 
    double (*A)[3] = moo.M; 
    double (&R)[3][3] = moo.M; 

    for (int r = 0; r != 3; ++r) { 
    for (int c = 0; c != 3; ++c) { 
     cout << A[r][c] << R[r][c] << ' '; 
     // notice A[r][c] and R[r][c] are the exact same object 
     // I'm using both to show you can use A and R identically 
    } 
    } 

    return 0; 
} 

나는 일반적으로 R 선호이상 때문에 고정 (즉, 요구 사항 인 경우 잠재적으로 double[10][3]를 가리 수)과 기준은 일반적으로 의지하는 길이의 모든 명확한 코드로 연결됩니다.

관련 문제