2017-09-14 23 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; 
}