2015-10-05 100 views
0

我试图创建一个列表(这是一个对象的私人memeber)对象的指针...创建对象的指针列表

所以我编码方案是两个组之间的模拟“英雄“S。每个英雄都有特殊的力量,物理属性等等和一系列目标。目标列表是指向Hero的指针列表。当我调用构造函数创建一个Hero时,除了目标列表之外,所有信息都用随机值初始化。到目前为止,我已经创建了两个Hero's,一队和二队的名单。我试图在队1中创建一个指向队列2的指针列表,反之亦然。 main()中的for循环系列是我拥有的最佳解决方案,但函数Hero :: setTarget“push_back”多次使用第一个Hero的地址。任何建议将不胜感激。

这里是我迄今排除Powers.h和Powers.cpp文件...

编辑:删除嵌套的for循环,但我仍然得到传递到我的列表中的同一个地址....

#include <iostream> 
    #include <list> 
    #include <random> 
    #include <ctime> 

    #include "Hero1.h" 
    #include "Powers.h" 

    using namespace std; 

    int main() 
    { 
///random number generator 
    default_random_engine generator(time(NULL)); 
    uniform_int_distribution<int> numHero(1,10); 

///lists of hero's, pointers to a hero, list iterators 
    list<Hero> team1; 
    list<Hero> team2; 
    Hero * hptr1; 
    Hero * hptr2; 
    list<Hero>::iterator hitr1; 
    list<Hero>::iterator hitr2; 

/// team 1 is created 
    int a = numHero(generator); 
    for(int x=0; x<a; x++) 
    { 
    hptr1 = new Hero(); 
    team1.push_back(*hptr1); 
    } 

/// team 2 is created 
    int b = numHero(generator); 
    for(int x=0;x<b;x++) 
    { 
    hptr2 = new Hero(); 
    team2.push_back(*hptr2); 
    } 

for(hitr2=team2.begin();hitr2!=team2.end();hitr2++) 
{ 
     hptr1->setTarget(hptr2); 
} 

for(hitr1=team1.begin();hitr1!=team1.end();hitr1++) 
{ 
    hptr2->setTarget(hptr1); 
} 

///printing results for list of targets 
int w =1; 
cout<<"target address "<<w<<endl; 
     hitr1=team1.begin(); 
     hptr1->displayTarget(); 

英雄是我的Hero.h

#ifndef HERO1_H_INCLUDED 
#define HERO1_H_INCLUDED 

#include <iostream> 
#include <random> 
#include <ctime> 
#include <list> 

#include "Powers.h" 


using namespace std; 

class Power; 

class Hero 
{ 
public: 

    Hero(); 
    // ~Hero(); 

    void setID(); 
    void setLoc(); 
    void setPhy(); 
    void setPowers(); 
    void setEquip(); 
    void setTarget(Hero *h); 

    int getID(){return id;} 
    int getLoc(int x); 
    int getPhy(int x); 

    void displayHero(); 
    void displayTarget(); 
    void displayPowers(); 


private: 
    int id; 
    int location[3]; 
    int physical [4]; 
    Power * powPtr; 
    Power * equipPtr; 
    Hero * targetPtr; 
    list<Power> powers; 
    list<Power> equipment; 
    list<Hero*> target; 
    list<Power>::iterator equipItr; 
    list<Power>::iterator powItr; 
    list<Hero*>::iterator targetItr; 

}; 

我Hero.cpp

#include "Hero1.h" 

default_random_engine generator(time(NULL)); 
uniform_int_distribution<int> distribution(100000,200000); 
normal_distribution<double> disto(50,10); 
uniform_int_distribution<int> randPow(1,3); 

Hero::Hero() 
{ 
    setLoc(); 
    setID(); 
    setPhy(); 
    setPowers(); 
    setEquip(); 
} 

void Hero::setLoc() 
{ 
    location[0] = 1; 
    location[1] = 2; 
    location[2] = 3; 
} 

void Hero::setID() 
{ 
    int a = distribution(generator); 
    id = a; 
} 

void Hero::setPhy() 
{ 
    double a = disto(generator); 
    double b = disto(generator); 
    double c = disto(generator); 
    double d = disto(generator); 

    physical[0] = a; 
    physical[1] = b; 
    physical[2] = c; 
    physical[3] = d; 

} 

void Hero::setPowers() 
{ 
    int a = randPow(generator); 
    for(int x=0;x<a;x++) 
    { 
    powPtr = new Power(getPhy(3)); 
    powers.push_back(*powPtr); 


    } 
} 


void Hero::setEquip() 
{ 
    int a = randPow(generator); 
    for(int x=0;x<a;x++) 
    { 
    equipPtr = new Power(getPhy(3)); 
    powers.push_back(*equipPtr); 
    } 

} 
void Hero::setTarget(Hero *h) 
{ 

    target.push_back(h); 

} 

void Hero::displayTarget() 
{ 
    int x =1; 
    for(targetItr=target.begin();targetItr!=target.end();targetItr++) 
    { 
     cout<<&targetPtr<<endl; 
     x++; 
    } 
    cout<<x<<endl; 

} 

int Hero::getLoc(int x) 
{ 
    int p; 
    p = location[x]; 
    return p; 
} 

int Hero::getPhy(int x) 
{ 
    int p; 
    p = physical[x]; 
    return p; 
} 
void Hero::displayPowers() 
{ 
    cout<<"Number of powers = "<<powers.size()<<endl<<endl; 
    for(powItr=powers.begin();powItr!=powers.end();powItr++) 
    { 
     powPtr->displayEffect(); 
    } 
} 

void Hero::displayHero() 
{ 
    cout<<"Id :\t\t\t\t\t"<<id 
     <<"\nLocation:\t\t\t\t"<<location[0]<<","<<location[1]<<","<<location[2] 
     <<"\nPhysical attributes:\tstrength\t"<<physical[0]<<"\n\t\t\tendurance\t"<<physical[1] 
     <<"\n\t\t\tagility\t\t"<<physical[2]<<"\n\t\t\tspeed\t\t"<<physical[3]<<endl<<endl; 

     displayPowers(); 
} 

回答

0

我与@TheUndeadFish的言论一致。

另外,我想补充以下意见:

list<Hero> team1; 
list<Hero> team2; 

而是保持“英雄”的对象列表中,它会被建议保持指针列表,以“英雄”对象

list<Hero*> team1; 
list<Hero*> team2; 

以上建议的方法有助于team1 heros保留team2 heros列表,反之亦然,所以这将有助于访问每个英雄的更新信息,因为指针/引用有助于访问对象数据的动态变化。

此外,for循环没有在原始代码中初始化hptr1和hptr2。这是可以做到如下:

///lists of hero's, pointers to a hero, list iterators 
    list<Hero*> team1;     <-- change done here 
    list<Hero*> team2;     <-- change done here 
    Hero * hptr1; 
    Hero * hptr2; 
    list<Hero*>::iterator hitr1;   <-- change done here 
    list<Hero*>::iterator hitr2;   <-- change done here 

/// team 1 is created 
    int a = numHero(generator); 
    for(int x=0; x<a; x++) 
    { 
    hptr1 = new Hero(); 
    team1.push_back(hptr1);    <-- change done here 
    } 

/// team 2 is created 
    int b = numHero(generator); 
    for(int x=0;x<b;x++) 
    { 
    hptr2 = new Hero(); 
    team2.push_back(hptr2);    <-- change done here 
    } 

for(hitr2=team2.begin();hitr2!=team2.end();hitr2++) 
{ 
    hptr2 = *hitr2;      <-- change done here 
    for(hitr1=team1.begin();hitr1!=team1.end();hitr1++) 
    { 
     hptr1 = *hitr1;     <-- change done here 
     hptr1->setTarget(hptr2); 
    } 
} 

for(hitr1=team1.begin();hitr1!=team1.end();hitr1++) 
{ 
    hptr1 = *hitr1;      <-- change done here 
    for(hitr2=team2.begin();hitr2!=team2.end();hitr2++) 
    { 
    hptr2 = *hitr2;      <-- change done here 
    hptr2->setTarget(hptr1); 
    } 
} 
+0

我试着运行你提供的代码,但我仍然有一个地址被重复随机次数。 我无法在这里发布代码,所以看看下一个答案... – bryan

0

我觉得我不得不说的更值得评论,然后回答这个问题,但是StackOverflow的怪异规则不允许我留下评论。也就是说,我认为您应该将“setTarget”重命名为“addTarget”,因为“setTarget”意味着每次调用它时都会覆盖一个变量值,而“addTarget”更好地表明您将会将目标添加到列表中。

另外,您应该考虑使用带有lambda函数而不是显式循环的std::for_each。我怀疑它会在性能或正确性方面造成任何显着差异,但它会使您的程序更具可读性,并且了解STL函数将帮助您提高编程技能。

1

我看到你的代码中的几个不同的问题,但让我们开始跟你问起一个...

setTarget每次通话,因为他们被称为与AREN指针时间做同样的事情在循环内不会更新。这是一个问题,可能来自在函数顶部声明所有变量。超越其目的的变量易受这样的错误影响(或者被重用于多种用途,然后使代码更难以理解和维护)。所以我强烈建议确定局部变量的确切位置。

例如:

/// lists of heroes 
    list<Hero> team1; 
    list<Hero> team2; 

/// team 1 is created 
    int a = numHero(generator); 
    for(int x=0; x<a; x++) 
    { 
     Hero * hptr1 = new Hero(); 
     team1.push_back(*hptr1); 
    } 

/// team 2 is created 
    int b = numHero(generator); 
    for(int x=0;x<b;x++) 
    { 
     Hero * hptr2 = new Hero(); 
     team2.push_back(*hptr2); 
    } 

for(list<Hero>::iterator hitr2=team2.begin();hitr2!=team2.end();hitr2++) 
{ 

    for(list<Hero>::iterator hitr1=team1.begin();hitr1!=team1.end();hitr1++) 
    { 
     hptr1->setTarget(hptr2); 
    } 
} 

for(list<Hero>::iterator hitr1=team1.begin();hitr1!=team1.end();hitr1++) 
{ 
    for(list<Hero>::iterator hitr2=team2.begin();hitr2!=team2.end();hitr2++) 
    { 
     hptr2->setTarget(hptr1); 
    } 
} 

如果你这样做,那么你就可以得到,因为hptr1hptr2不存在在那里setTarget被称为编译错误。这正是你想要的 - 编译器把你的注意力放在一个错误上。

所以后来这些循环可以被纠正,就像这样:

for(list<Hero>::iterator hitr2=team2.begin();hitr2!=team2.end();hitr2++) 
{ 

    for(list<Hero>::iterator hitr1=team1.begin();hitr1!=team1.end();hitr1++) 
    { 
     Hero& target = *hitr2; 
     hitr1->setTarget(&target); 
    } 
} 

接下来,第二个问题:您填写的列表时泄漏内存:

Hero * hptr1 = new Hero(); 
team1.push_back(*hptr1); 

,将动态分配一个英雄,然后复制它的值到另一个在列表中创建的英雄 - 因为这是push_back如何与list<Hero>类似的工作。然后指向动态分配的指针会丢弃(或者在您最初发布的代码中重用),所以没有任何事情可以释放该内存。

你真正想要做的更像是:

team1.push_back(Hero()); 
0

从原来的程序,下面的代码段也需要修改:

void Hero::displayTarget() 
{ 
    int x = 0;         <-- change done here (not important) 
    for (targetItr=target.begin(); targetItr!=target.end(); targetItr++) 
    { 
     cout << *targetItr << endl;    <-- change done here 
     x++; 
    } 
    cout<<x<<endl; 
} 

注:

  1. targetPtr成员英雄类未初始化的原始代码。
  2. 在displayTarget()中,始终打印了targetPtr,但未更新每次迭代的targetItr。

此外,改变显示的代码在main():

cout<<"target addresses in team 1"<<endl; 
     hitr1=team1.begin(); 
     hptr1 = *hitr1;      <-- change done here 
     cout<<"address of team 1 pointer "<<hptr1<<endl; 
     hptr1->displayTarget(); 
     cout<<endl<<"-------------"<<endl; 
     cout<<"target addresses in team 2"<<endl; 
     hitr2=team2.begin(); 
     hptr2 = *hitr2;      <-- change done here 
     cout<<"addreass of team 2 pointer "<<hptr2<<endl; 
     hptr2->displayTarget(); 

希望这有助于你。祝一切顺利。