2015-12-21 122 views
0

我有兩個類:GenomeRankedNodeRandomRankedTPNGeneratorRandomRankedTPNGenerator責任只是隨機創建一個GenomeRankedNodeGenomeRankedNode有四個屬性:int,int,int *和int。我的主要有一個載體應該使用RandomRankedTPNGenerator填充。爲了這個目的,在主,我有:向對象添加對象會覆蓋現有對象

std::vector<GenomeRankedNode*> population; 
population.resize(50); 
for (int i = 0; i < popsize; i++) { 
    RandomRankedTPNGenerator* generator = new RandomRankedTPNGenerator(); 
    GenomeRankedNode node* = generator->randomNode(numParents); 
    population[i] = node; 
    delete generator; 
} 

RandomRankedTPNGenerator中,重要的功能是randomNode():

GenomeRankedNode* RandomRankedTPNGenerator::randomNode(int numParents){ 
    int function = randomFunction(); //just gets a random number 
    int* weights = randomWeights(numParents); //just gets a random number 
    int variance = randomVariance(); //just gets a random number 
    GenomeRankedNode* node = new GenomeRankedNode(function, numParents, weights, variance); 
    return node; 
} 

上面的代碼被產生隨機GenomeRankedNode正常。問題是,在人口,當我添加的對象,現有的顯然是「覆蓋」(我知道他們實際上並沒有被覆蓋...)。另一方面,人口正在填充不同的地址。如果我使用RandomRankedTPNGenerator的不同實例創建GenomeRankedNodeGenomeRankedNode在不同的地址正在創建對象,爲什麼都在人口指向相同的內存空間中的指針導致價值被指出人口[我],每一個我都一樣嗎?

下面是GenomeRankedNode.cpp代碼:

int function; 
int* weights; 
int numNodeParents; 
int variance; 

double vars[11] = {0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50}; 

GenomeRankedNode::GenomeRankedNode() 
{ 
    function = 0; 
    weights = 0; 
    numNodeParents = 1; 
    variance = 0; 
} 

GenomeRankedNode::GenomeRankedNode(int inFunction, int inNumParents, int* inWeights, int inVariance) 
{ 
    function = inFunction; 
    numNodeParents = inNumParents; 
    weights = inWeights; 
    variance = inVariance; 
} 

GenomeRankedNode::GenomeRankedNode(GenomeRankedNode* inNode) 
{ 
    function = inNode->getFunction(); 
    numNodeParents = inNode->getNumParents(); 
    weights = inNode->getWeights(); 
    variance = inNode->getVariance(); 
} 

GenomeRankedNode::GenomeRankedNode(const GenomeRankedNode &inNode) 
{ 
    function = inNode.getFunction(); 
    numNodeParents = inNode.getNumParents(); 
    variance = inNode.getVariance(); 

    //deep copy 
    if (inNode.getWeights()){ 
     weights = new int[numNodeParents]; 
     for (int i = 0; i < numNodeParents; i++) 
      weights[i] = inNode.getWeights()[i]; 
    } 
} 

GenomeRankedNode& GenomeRankedNode::operator= (const GenomeRankedNode &inNode) 
{ 

    //self-assignment check 
    if (this == &inNode) 
     return *this; 

    function = inNode.getFunction(); 
    numNodeParents = inNode.getNumParents(); 
    variance = inNode.getVariance(); 

    // explicitly deallocate values 
    delete[] weights; 

    // deep copy 
    if (inNode.getWeights()){ 
     weights = new int[numNodeParents]; 
     for (int i = 0; i < numNodeParents; i++) 
      weights[i] = inNode.getWeights()[i]; 
    } 
    else 
     weights = 0; 

    return *this; 
} 

GenomeRankedNode::~GenomeRankedNode(void) 
{ 
    delete &function; 
    delete &numNodeParents; 
    delete weights; 
    delete &variance; 
} 

int GenomeRankedNode::getFunction() const 
{ 
    return function; 
} 

int* GenomeRankedNode::getWeights() const 
{ 
    return weights; 
} 

int GenomeRankedNode::getNumParents() const 
{ 
    return numNodeParents; 
} 

int GenomeRankedNode::getVariance() const 
{ 
    return variance; 
} 

void GenomeRankedNode::setWeights(int *inWeights) 
{ 
    weights = inWeights; 
} 

void GenomeRankedNode::setFunction(int inFunction) 
{ 
    function = inFunction; 
} 

void GenomeRankedNode::setVariance(int inVariance) 
{ 
    variance = inVariance; 
} 

double GenomeRankedNode::getRealVariance(int inVariance) const 
{ 
    return vars[inVariance]; 
} 

要檢查不當行爲,我加入到主:

for (int i = 0; i < population.size(); i++){ 
    cout << population.at(i)->toString(); 

}

鑑於population.size ()= 3,輸出爲:

Function: 1 
Weights: 1 1 
Variance: 2 

Function: 1 
Weights: 1 1 
Variance: 2 

Function: 1 
Weights: 1 1 
Variance: 2 

在另一方面,如果我添加一行:

cout << population.at(i)->toString(); 

中,我用它來生成隨機GenomeRankedNode對象的循環,我有:

Function: 0 
Weights: 3 4 
Variance: 1 

Function: 1 
Weights: 4 1 
Variance: 3 

Function = 1 
Weights = 1 1 
Variance = 2 

鑑於此,我的結論:出於某種原因,所有創建的GenomeRankedNode指向內存中的相同插槽。因此,每當一個新的GenomeRankedNode被實例化時,所有其他指針(GenomeRankedNode *)都將更新其指針值!它類似於淺層和深層複製問題,但我不知道它起源於何處!

+1

歡迎來到Stack Overflow。請注意,當你問一個明顯關於C++的問題時,你容易激怒人們,但用[tag:c]和[tag:C++]標記它 - 避免雙重標記,除非問題明確地說明了C和C++。 –

+2

我的猜測是,你總是生成相同的節點,因爲你從同一個隨機生成器開始迭代。向上移動隨機生成器並退出for循環,然後重試。 – NathanOliver

+1

您可能不想在每次迭代中創建一個RandomRankedTPNGenerator,除非強制該行爲的類的設計有所不同。你需要知道這是如何工作的,並保證每次建造課程時都有不同的行爲。 –

回答

2

我看到的一個問題是,您將人口的第i個值設置爲GenomeRankedType而不是GenomeRankedType*(您說人口存儲的類型)。

所以修改的代碼的頂部部分:

std::vector<GenomeRankedNode*> population; 
population.resize(50); 
for (int i = 0; i < popsize; i++) { 
    RandomRankedTPNGenerator* generator = new RandomRankedTPNGenerator(); 
    GenomeRankedNode* node = generator->randomNode(numParents); 
    population[i] = node; 
    delete generator; 
} 

讓我知道如果這能幫助你!

+0

你是對的。對於那個很抱歉。這是一個錯字。該行爲在您的修改中仍然存在。 – ryouma

+0

酷!我會檢查你的代碼的其餘部分,看看我能否找到其他的東西。 – spektr

0

我感動:

int function; 
int* weights; 
int numNodeParents; 
int variance; 

從GenomeRankedNode.cpp到GenomeRankedNode.h爲私人。這解決了這個問題。