2017-09-14 1 views
1

J'ai deux classes, nous allons les appeler A et BNouveau pointeur dans la méthode de classe doit être casté dans une référence

class A: 
{ 
    public: 
    //Some functions 

    A *getNewA() const; 

    private: 
    //some attributes 
} 

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

Dans le code principal, je doit générer un nouveau A grâce au Méthode A :: getNewA(). Et ce doit aller à B :: reftoA, comme il est écrit dans la classe B.

Voici la méthode A :: getNewA():

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

OK. Alors maintenant, j'appelle getNewA et que vous souhaitez stocker les résultats dans reftoA, qui est une référence à A. En fonction B (qui prennent une référence à A comme paramètre)

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

Je pensais que cela aurait dû être travailler, mais ce ne sera pas le cas. Parce que lors du déréférencement, reftoA prendra toujours l'objet this et non le nouvel objet alloué.

Soyons plus clairs et modifions les fonctions de sortie des résultats

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

Voici une des sorties:

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

Je ne peux pas obtenir ce « nouveau pointeur généré » pour être le même que le nouveau pointeur, le A :: getNewA() retourne après avoir alloué la mémoire. Bien sûr, je suppose qu'il est utile de déréférencer le pointeur pour le stocker dans une référence. Je sais que les références sont utilisées avec un objet existant. Peut-être que le nouvel objet A :: getNewA() devrait allouer de la mémoire pour ne fonctionnera pas comme prévu.

je pouvais utiliser un pointeur de référence à la place dans B :: foo(), je sais, mais je ne peux pas

Je pense que je comprends mal quelque chose refrence et pointeur, mais je ne savoir quoi.

Toute aide grandement appréciée

+2

Attendez, quoi? 'retour A'? Comment ça se construit? Pouvez-vous s'il vous plaît essayer de créer un [Exemple minimal, complet et vérifiable] (http://stackoverflow.com/help/mcve) pour nous montrer? –

+0

En outre, vous avez une fuite de mémoire. Vous supprimez le pointeur retourné par 'getNewA' (bien, en supposant que vous retourniez réellement' newA'), vous n'avez donc rien à 'supprimer '. –

+0

Enfin, et la source probable de votre problème: * Vous ne pouvez pas réaffecter une référence *. Ce que vous faites est d'assigner * à * l'objet *. Vous faites effectivement 'reftoA.operator = (* (paramA.getNewA())) ' –

Répondre

1

Oui, vous comprenez mal quelque chose.

getNewA() renvoie un pointeur. ce n'est pas un pointeur intelligent, vous voulez vous pencher sur ceux-ci et c'est tout ce que je dirai à ce sujet. En retournant un pointeur, vous devez garder une référence à ce pointeur, sinon vous ne pourrez pas le supprimer et vous aurez une fuite de mémoire.

Ainsi, vous devez avoir quelque part A* a = A::getNewA() et plus tard, lorsque vous n'en avez plus besoin delete a;

Lorsque vous devez passer une référence à A, vous pouvez faire foo(*a) qui déréférencer le pointeur et transmettre une référence à l'objet vers lequel il pointe.

Mais en résumé, pour tout nouveau code, pointeurs intelligents; il n'y a pas d'excuse pour ne pas les utiliser.Remarque: Votre exemple de code a rencontré quelques problèmes; tel que getNewA n'était pas statique; Je vais prendre le code comme un exemple de votre compréhension, et non un exemple de travail. Edit: À la relecture de votre exemple, le getNewA est intentionnellement non statique. Je pense que cette question est en fait un problème XY (c'est-à-dire que vous posez une question à laquelle vous vous êtes imposé, mais qui n'est pas votre problème réel); mais j'espère que cela répond à votre malentendu sur les pointeurs et les références.

4

Le problème est que vous ne pouvez pas réaffecter une référence. Vous ne pouvez modifier que la valeur de l'objet référencé.

donc vous devez initialiser la référence dans la liste d'initialisation du constructeur de la classe B.

prendre en compte qu'il ya une faute de frappe dans l'extrait de code

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

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

Je pense que vous voulez dire

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

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

Essayez toujours de fournir un exemple complet vérifiable.

Voici un programme démonstratif

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

Sa sortie est

New pointer 0x2b392afbec20 
this pointer0x7ffd287ad0af 
&reftoA 0x2b392afbec20 

Comme vous pouvez voir les valeurs de la New pointer et &reftoA sont égaux entre eux.

Pour le rendre plus clair, considérons un exemple très simple

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

La sortie du programme est

x = 20 
y = 20 
r = 20 

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

Cette déclaration

r = y; 

ne force pas la référence de renvoyer l'objet y. Il vient de réaffecter la valeur de l'objet référencé x.

Les références doivent être initialisées lors de leur création.

+0

Merci beaucoup! Après avoir compris les références ne pouvaient pas être réaffectées (ce qui me semble maintenant logique) j'avais pensé à écrire quelque chose comme le tien. Mais tu as fait mieux, je comprends mieux maintenant. Merci pour votre réponse, il m'est utile de comprendre comment fonctionnent les références. – frankee

+0

@frankee Pas du tout. Je vous en prie.:) –

0

Vous ne remettons pas le pointeur dans la getNewA -Méthode

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

Et si vous voulez réattribuer la référence à vous pouvez utiliser un std::reference_wrapper

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

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