2017-09-14 47 views
1

我有兩個班,我們姑且稱之爲A和B類方法的新指針必須被鑄造成一個參考

class A: 
{ 
    public: 
    //Some functions 

    A *getNewA() const; 

    private: 
    //some attributes 
} 

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

在主代碼,我必須產生一個新的A感謝A :: getNewA()方法。這必須去B :: reftoA,寫在B級

這裏是A :: getNewA()方法:

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

確定。所以,現在我打電話getNewA和要存儲reftoA的結果,這是一個參考到A在B的功能(這需要參照A作爲參數)

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

我想這應該是工作,但它不會。 因爲當解引用時,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

等等,什麼? '返回A'?這是如何構建的?你能否請嘗試創建一個[最小,完整和可驗證示例](http://stackoverflow.com/help/mcve)向我們展示? –

+0

另外,你有內存泄漏。你放棄'getNewA'返回的指針(當然,假設你實際返回'newA'),所以你真的沒有什麼可以「刪除」的。 –

+0

最後,您的問題的可能來源:*您不能重新分配參考*。你正在做的是將*分配給*對象*。你真的在做'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; 
^^^^^^^^^^^ 
} 

總是試圖提供一個可驗證的完整示例。

這裏是一個示範項目

#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 

正如你可以看到New pointer&reftoA的值相等對方。

爲了更清楚考慮一個很簡單的例子

#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 - 方法

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; 
}