C++ Logic Bug: Trying to Generate Unique ObjectIDs for all Instances Created, Counter Registering Incorrectly

StackOverflow https://stackoverflow.com/questions/9200285

  •  27-04-2021
  •  | 
  •  

Domanda

I am working on a project that must allow all instances created to have a unique objID. All classes inherit from one base class that has a static variable that increments whenever any of the concrete classes constructor(s) are called. The counter keeps running until program is quit.

The problem I am having is when I use an array (any C++ containers), the objID registers more then one increment.

For example: In my main() I created a vector<ConcreteClassA> cc; and did a push_back(...) twice.

My Output was:

objID = 5, and count = 2

Expected Result:

objID = 2, and count = 2

I am not sure why my ObjID is registering more then once for each push_back(...). I have gone through and checked all locations to make sure my assign() is only called in constructors of my concrete classes.

Please advise.

//===========================================================================   
//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...
È stato utile?

Soluzione

You have to account for copies of the object. In C++ vector<T>::push_back() puts a copy of the object into the vector. The temp instances that you created in the function call are getting destroyed. That is why the "created" count is higher that the "active" count.

If you really want to be stingy about creating instances of the object, maybe you should store pointers in the vector. That way you have to explicitly create and destroy them.

Here's a nice post on something like that: https://stackoverflow.com/a/1361227/2174

Altri suggerimenti

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

Woah, I haven't checked the operator precedence there, but I'd write

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

without even thinking twice. (A good guideline is, that if you can have a doubt or would want to check, you should write it more clearly).

And, yes, that should just be

void IBase::decrementCount()
{
    --count;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top