Ошибка логики C ++: Попытка сгенерировать уникальные ObjectID для всех созданных экземпляров, неправильная регистрация счетчика - PullRequest
0 голосов
/ 08 февраля 2012

Я работаю над проектом, который должен позволить всем созданным экземплярам иметь уникальный objID.Все классы наследуются от одного базового класса, который имеет статическую переменную, которая увеличивается всякий раз, когда вызывается любой из конкретных конструкторов классов.Счетчик продолжает работать до завершения программы.

Проблема, с которой я сталкиваюсь, заключается в том, что при использовании массива (любых контейнеров C ++) objID регистрирует более одного приращения.

Например: Inмой main() Я создал vector<ConcreteClassA> cc; и дважды push_back(...).

Мой вывод был:

objID = 5, and count = 2

Ожидаемый результат:

objID = 2, and count = 2

Я не уверен, почему мой ObjID регистрируется более одного раза для каждого push_back(...),Я прошел и проверил все местоположения, чтобы убедиться, что мой assign() вызывается только в конструкторах моих конкретных классов.

Пожалуйста, сообщите.

//===========================================================================   
//Main.cpp

#include "ConcreteClassA.h";

#include <iostream>
#include <vector>
#using namespace std;

int main()
{
    vector<ConcreteClassA> c1;
    cc.push_back( ConcreteClassA() );
    cc.push_back( ConcreteClassA() );

    return 0;
}

    //objID is off for some reason....
    //Expected Results: count = 2, objID = 2
    //Output: count = 2, objID = 5

//===========================================================================
//IBase.h file
private: 
    static int objID;      //used to assign unique IDs
    static int count;      //track how many stances of all objs are active

protected:        
    const int assignID();  //return a new ID
    void decrementCount(); //decrement count, when an obj is removed
//===========================================================================

//IBase.cpp
int IBase::objID = 0;
int IBase::count= 0;

const int IBase::assignID()
{
    ++ this->count;
    ++ this->objID;

    return ( this->objID );
}

void IBase::decrementCount()
{
    -- this->count;
}

//===========================================================================
ConcreteClassA.h

ConcreteClassA();     //default constructor
ConcreteClassA(...);  //couple overloaded constructors
~ConcreteClassA();    //destructor

ConcreteClassA( const ConcreteClassA &cc );           //copy constructor
ConcreteClassA& operator=(const ConcreteClassA &cc);  //assignment operator

//more methods....

//===========================================================================
ConcreteClassA.cpp

//destructor makes sure instances tracking counter is decremented
ConcreteClassA::~ConcreteClassA()
{
    this->decrementCount();
}

//only constructors and assignemnt operators call assign() method
ConcreteClassA::ConcreteClassA()
{
    //some other initialization...
    this->assignID();
}
//All other methods implementation left out for sensitivity of real estate...

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Вы должны учитывать копии объекта.В C ++ vector<T>::push_back() помещает копию объекта в вектор.Временные экземпляры, которые вы создали в вызове функции, уничтожаются.Вот почему число «созданных» больше, чем количество «активных».

Если вы действительно хотите скупиться на создание экземпляров объекта, возможно, вам следует хранить указатели в векторе.Таким образом, вы должны явно создавать и уничтожать их.

Вот хороший пост на что-то вроде этого: https://stackoverflow.com/a/1361227/2174

0 голосов
/ 09 февраля 2012
void IBase::decrementCount()
{
    -- this->count;
}

Воу, я не проверял там приоритет оператора, но я бы написал

void IBase::decrementCount()
{
    -- (this->count);
}

, даже не подумав дважды. (Хорошая рекомендация заключается в том, что если у вас есть сомнения или вы хотите проверить, вы должны написать это более четко).

И, да, это должно просто быть

void IBase::decrementCount()
{
    --count;
}
...