2015-10-05 98 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(); 

希望這有助於你。祝一切順利。