2017-09-14 4 views
1

, 나는 해야받는 새로운 덕분 생성의 메인 코드에서 A와 B새로운 포인터 참조로 주조해야 내가이 개 수업을

class A: 
{ 
    public: 
    //Some functions 

    A *getNewA() const; 

    private: 
    //some attributes 
} 

class B: 
{ 
    public: 
    //Some functions 
    private: 
    A &reftoA; 
} 

을 부르 자 A :: getNewA() 메소드.

A *A::getNewA() 
{ 
    A *newA = new A; 
    return newA; 
} 

OK : 그리고이 클래스 B. 여기

에 기록 된대로, B :: reftoA로는 A :: getNewA() 메소드가되어 가야한다. 따라서 지금은 getNewA를 호출 reftoA에 결과를 저장할, I이 했어야 생각

B::foo(A &paramA) 
{ 
    reftoA = *(paramA.getNewA()); 
} 

(파라미터로서 참조를 취할)는 B 기능에서 A.에 참조 인 작동하지만, 그렇지는 않습니다. 역 참조 할 때 reftoA는 항상이 객체를 취하고 새로 할당 된 객체를 취하지 않기 때문에.

의가 명확하게하자의이 결과

여기
A * A::getNewA() 
{ 
    A *newA = new A; 
    std::cout << "New pointer " << newA << std::endl; 
    std::cout << "this pointer" << this << std::endl; 

    return A; 
} 

void B::foo(A &paramA) 
{ 

    reftoA = *(paramA.getNewA()); 
    std::cout << "new generated pointer " << &reftoA << std::endl; 
} 

출력 중 하나입니다 출력 기능을 수정할 수 :

New pointer : 004FFAEC 
this pointer: 0069D888 
New generated pointer : 0069D888 //Expected : 004FFAEC 

나는 일이 "새로운 생성 된 포인터"를 얻을 수 없다 메모리를 할당 한 후 A :: getNewA()가 반환하는 새 포인터와 동일합니다. 물론 포인터를 역 참조하여 포인터를 참조에 저장하는 것이 좋습니다. 참조는 기존 객체와 함께 사용됩니다. 어쩌면 새로운 객체 A :: getNewA()가 예상대로 작동하지 않을 메모리를 할당해야합니다.

내가 대신 B에서 참조 포인터를 사용할 수

:: foo는(), 나도 알아,하지만 내가 할 수없는 내가에 refrence와 포인터에 대해 뭔가 오해하고 있어요,하지만 난하지 않는 생각

무엇을 알고.

큰 도움이된다면

+2

대기를 사용할 수 있습니다, 무엇을? 'return A'? 그게 어떻게 지어 집니까? 우리에게 보여줄 수있는 [Minimal, Complete, Verifiable Example] (http://stackoverflow.com/help/mcve)을 만드시겠습니까? –

+0

또한 메모리 누수가 있습니다. 'getNewA'에 의해 리턴 된 포인터를 버리고 (사실,'newA'를 리턴한다고 가정), 실제로'delete' 할 것이 없습니다. –

+0

마지막으로, 문제의 가능한 원인은 다음과 같습니다. * 참조를 다시 할당 할 수 없습니다 *. 당신이하는 일은 * * * object *를 지정하는 것입니다. 당신은 효과적으로'reftoA.operator = (* (paramA.getNewA()))' –

답변

1

예, 오해입니다.

getNewA()이 포인터를 반환 중입니다. 그것은 똑똑한 포인터가 아닙니다. 당신은 그것들을 들여다보고 싶습니다. 그리고 그것은 제가이 문제에 관해 말할 것입니다.

포인터를 반환 할 때이 포인터에 대한 참조를 유지해야합니다. 그렇지 않으면 포인터를 삭제할 수 없기 때문에 메모리 누수가 발생합니다. 그러므로 당신은 어딘가에 A* a = A::getNewA()을 가지고 있어야하고 나중에 더 이상 필요가 없을 때 delete a;

A에 대한 참조를 전달해야하는 경우 foo(*a)을 사용하면 포인터를 역 참조하고 포인터가 가리키는 객체에 대한 참조를 전달할 수 있습니다.

요약하면, 모든 새 코드에 대해 스마트 포인터; 그들을 사용하지 않아도됩니다.

사이드 노트 : 코드 예제에는 몇 가지 다른 문제가 있습니다. getNewA는 정적이 아닙니다. 코드를 실용적인 예제가 아닌 이해의 실제 예제로 사용하겠습니다.

편집 : 예제를 다시 읽으면 getNewA는 의도적으로 비 정적입니다. 나는이 질문이 실제로 XY 문제라고 생각한다. (즉, 스스로에게 강요 한 질문을하지만 실제 문제는 아니다.) 그러나 이것이 포인터와 참조에 대한 오해를 해결하기를 바랍니다.

4

문제는 참조를 재 할당 할 수 없다는 것입니다. 참조 된 객체의 값만 변경할 수 있습니다.

그래서 당신은 당신의 코드에 오타

A*A::getNewA() 
{ 
A *newA = new A; 
std::cout << "New pointer " << newA << std::endl; 
std::cout << "this pointer" << this << std::endl; 

return A; 
^^^^^^^^^ 
} 

내가 당신 말은 생각이 있음을

고려해야 클래스 B의 생성자의 초기화 목록에서 참조를 초기화해야

A*A::getNewA() const 
       ^^^^^ 
{ 
A *newA = new A; 
std::cout << "New pointer " << newA << std::endl; 
std::cout << "this pointer" << this << std::endl; 

return newA; 
^^^^^^^^^^^ 
} 

확인 가능한 완전한 예를 제공하려고 항상 시도하십시오. 여기

사용하면 New pointer&reftoA의 값을 참조 다른 각각 동일한 수 있듯이

#include <iostream> 

class A 
{ 
public : 
    //Some functions 

    A* getNewA() const 
    { 
     A *newA = new A; 
     std::cout << "New pointer " << newA << std::endl; 
     std::cout << "this pointer" << this << std::endl; 

    return newA; 
    } 

private : 
    //some attributes 
}; 

class B 
{ 
public : 
    B(const A& a) : reftoA(*a.getNewA()) 
    { 
     std::cout << "&reftoA " << &reftoA << std::endl; 
    } 
private : 
    A& reftoA; 
}; 

int main() 
{ 
    A a; 

    B b(a); 

    return 0; 
} 

출력은

New pointer 0x2b392afbec20 
this pointer0x7ffd287ad0af 
&reftoA 0x2b392afbec20 

을하는 프로그램을 실증한다.

이 좀 더 명확 매우 간단한 예를 고려하려면

#include <iostream> 

int main() 
{ 
    int x = 10; 
    int y = 20; 

    int &r = x; 

    r = y; 

    std::cout << "x = " << x << std::endl; 
    std::cout << "y = " << y << std::endl; 
    std::cout << "r = " << r << std::endl; 

    std::cout << std::endl; 

    std::cout << "&x = " << &x << std::endl; 
    std::cout << "&y = " << &y << std::endl; 
    std::cout << "&r = " << &r << std::endl; 

    return 0; 
} 

프로그램 출력은

x = 20 
y = 20 
r = 20 

&x = 0x7ffd88ad47a8 
&y = 0x7ffd88ad47ac 
&r = 0x7ffd88ad47a8 

r = y; 

개체를 참조 할 참조를 강요하지 않았다이 문입니다 y. 방금 참조 된 객체 x의 값을 재 할당했습니다.

참조를 생성 할 때 초기화해야합니다.

+0

고마워요! 참조를 이해 한 후 재 할당 할 수 없었습니다. (지금은 나에게있어 논리적 인 것처럼 보입니다) 나는 당신과 비슷한 것을 쓰려고 생각했습니다. 하지만 당신이 더 잘 했어요. 이제는 더 잘 이해합니다. 답해 주셔서 감사합니다. 참조가 작동하는 방식을 이해하는 것이 좋습니다. – frankee

+0

@frankee 아니요. 천만에요.:) –

0

당신은 getNewA -Method

A* A::getNewA() 
{ 
    A *newA = new A; 
    return A; // you are returning A and not newA 
} 

에 포인터를 반환하지 않습니다 그리고 당신이에 대한 참조를 다시 할당하려는 경우 당신은 std::reference_wrapper

class B : 
{ 
public : 
void foo(A& paramA) { 
    reftoA = *(paramA.getNewA()); 
} 

private : 
std::reference_wrapper<A> reftoA; 
}