why destructor function called twice

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David

    #1

    why destructor function called twice

    Hi all,
    something wrong with my code, it seems that the destructor function
    has been called twice. I don't know why.here is my codes
    Fixture.h
    #ifndef _FIXTURE_H
    #define _FIXTURE_H

    #include <string>
    #include <map>
    #include <list>
    #include <vector>
    #include <utility>
    #include <algorithm>

    using namespace std;

    class Fixture
    {
    protected:
    string fixturename;
    vector<string>f aces
    map<string,vect or<string points;
    map<string,stri ng>locators;
    public:
    Fixture();
    Fixture(const Fixture &fix);
    ~Fixture();
    void AddLocateFace(c onst string &face);
    void AddLocatePoint( const string &face,const string &point);
    void AddLocator(cons t string &point,const string &locator);
    };

    Fixture.cpp
    #include "Fixture.h"
    #include "PrjError.h "

    #include <iostream>


    Fixture::Fixtur e()
    {
    fixturename="";
    }
    Fixture::Fixtur e(const Fixture &fix)
    {
    fixturename=fix .fixturename;
    faces=fix.faces ;
    points=fix.poin ts;
    locators=fix.lo cators;
    }
    Fixture::~Fixtu re()
    {

    }

    void Fixture::AddLoc ateFace(const string &face)
    {
    vector<string>: :iterator ii;
    int found=0;
    for(ii=faces.be gin();ii!=faces .end();ii++)
    {
    if(*ii==face)
    {
    found=1;
    break;
    }
    }
    if(found==0)
    faces.push_back (face);
    else
    throw PrjError::PrjEr ror(PrjError::E RR_ALREADY_EXIS T);
    }

    void Fixture::AddLoc atePoint(const string &face,const string &point)
    {
    map<string,vect or<string::iter ator ii;
    vector<stringte mp;
    vector<string>: :iterator kk;
    kk=find(faces.b egin(),faces.en d(),face);
    if(kk==faces.en d())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    ii=points.find( face);
    if(ii==points.e nd())
    {
    pair<map<string ,vector<string: :iterator,boolp ;
    temp.push_back( point);
    map<string,vect or<string::valu e_type newpoint(face,t emp);
    p=points.insert (newpoint);
    if(p.second==fa lse)
    throw PrjError::PrjEr ror(PrjError::E RR_INSERT_NEW);
    ii=p.first;
    }
    else
    {
    kk=find(ii->second.begin() ,ii->second.end(),p oint);
    if(kk!=ii->second.end() )
    throw PrjError::PrjEr ror(PrjError::E RR_ALREADY_EXIS T);
    ii->second.push_ba ck(point);
    }
    }

    void Fixture::AddLoc ator(const string &point,const string &locator)
    {
    map<string,stri ng>::iterator ii;
    map<string,vect or<string::iter ator jj;
    vector<string>: :iterator kk;
    int found=0;

    //find the point
    for(jj=points.b egin();jj!=poin ts.end();jj++)
    {
    kk=find(jj->second.begin() ,jj->second.end(),p oint);
    if(kk!=jj->second.end() )
    {
    found=1;
    break;
    }
    }

    if(found==0)
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    ii=locators.fin d(point);
    if(ii!=locators .end())
    throw PrjError::PrjEr ror(PrjError::E RR_ALREADY_EXIS T);

    pair<map<string ,string>::itera tor,boolp;
    map<string,stri ng>::value_type newlocator(poin t,locator);
    p=locators.inse rt(newlocator);

    if(p.second==fa lse)
    PrjError::PrjEr ror(PrjError::E RR_INSERT_NEW);
    ii=p.first;
    }


    ///////////////////////////////////////////////////////////////////////////////
    Machine.h

    #ifndef _MACHINE_H
    #define _MACHINE_H

    #include <string>

    using namespace std;

    class Machine
    {
    protected:
    string machinename;
    public:
    Machine();
    Machine(const Machine & mac);
    ~Machine();
    inline void SetMachinename( const string &name){machinen ame=name;}
    inline string GetMachinename( ){return machinename;}
    };

    #endif

    Machine.cpp
    #include "Machine.h"

    Machine::Machin e()
    {
    machinename="";
    }
    Machine::Machin e(const Machine &mac)
    {
    machinename=mac .machinename;
    }

    Machine::~Machi ne()
    {
    }

    ///////////////////////////////////////////////////////////////////////
    PrjError.h

    #ifndef _PRJERROR_H
    #define _PRJERROR_H


    class PrjError
    {
    public:
    enum ERROR_ENUM
    {
    ERR_BAD_PRJNAME ,
    ERR_BAD_SETUPNA ME,
    ERR_ALREADY_EXI ST,
    ERR_BAD_CADNAME ,
    ERR_NOT_FIND,
    ERR_INSERT_NEW,

    ERR_MAX_NUM
    };
    PrjError(ERROR_ ENUM err);
    const char* geterrormsg(ERR OR_ENUM err);
    const char* geterrormsg();
    inline int geterror(){retu rn (int)cur_err;}

    protected:
    int cur_err;
    static const char*msg[ERR_MAX_NUM];
    };


    #endif

    PrjError.cpp
    #include "PrjError.h "

    const char *PrjError::msg[PrjError::ERR_M AX_NUM]={
    "ERROR: Project name can't be empty",
    "ERROR:Setu p name can't be empty",
    "ERROR: Project has already existed",
    "ERROR: CAD name can't be empty",

    "Error:Can' t find",
    "Error:Fail to insert new element"
    };

    PrjError::PrjEr ror(ERROR_ENUM err)
    {
    cur_err=err;
    };

    const char*PrjError:: geterrormsg(ERR OR_ENUM err)
    {
    return this->msg[err];
    }
    const char* PrjError::geter rormsg()
    {
    return this->msg[cur_err];
    }

    ///////////////////////////////////////////////////////////////////////////////////
    PrjManager.h

    #ifndef _PRJMANAGER_H
    #define _PRJMANAGER_H

    #include <map>
    #include <list>
    #include <string>

    #include "Project.h"
    #include "PrjError.h "

    using namespace std;

    class PrjManager{

    public:
    PrjManager();
    ~PrjManager();

    void AddPrj(const Project &prj,const string &prjname);
    void SavePrj(const Project &prj);
    void OpenPrj(const string &prjname);
    string GetCurrentprj() ;
    void SetCurrentprj(c onst string &prjname);

    //this is only for test
    void GetPrjlist();

    protected:
    map<string,Proj ect*prjlists;
    Project *currentPrj;
    string currentPrjName;
    };

    #endif

    PrjManager.cpp
    #include "PrjManager .h"
    #include <iostream>

    PrjManager::Prj Manager()
    {
    currentPrjName= "";

    }

    PrjManager::~Pr jManager()
    {
    map<string,Proj ect*>::iterator ii;

    for(ii=prjlists .begin();ii!=pr jlists.end();++ ii)
    prjlists.erase( ii);
    }

    void PrjManager::Add Prj(const Project &prj,const string &projname)
    {

    map<string,Proj ect*>::iterator ii;
    Project *newPrj=NULL;

    char name[256];
    strcpy(name,pro jname.c_str());
    if(projname.len gth()==0)
    throw PrjError::PrjEr ror(PrjError::E RR_BAD_PRJNAME) ;

    ii=prjlists.fin d(projname);
    if(ii!=prjlists .end())
    throw PrjError::PrjEr ror(PrjError::E RR_ALREADY_EXIS T);

    newPrj=new Project(prj);
    prjlists[projname]=newPrj;

    }

    string PrjManager::Get Currentprj()
    {
    return currentPrjName;
    }

    void PrjManager::Set Currentprj(cons t string &prjname)
    {
    map<string,Proj ect*>::iterator ii;

    if(prjname.leng th()==0)
    currentPrjName= "";
    if(prjname!=cur rentPrjName)
    {
    ii=prjlists.fin d(prjname);
    if(ii==prjlists .end())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    currentPrjName= ii->first;
    currentPrj=ii->second;
    }
    }



    void PrjManager::Get Prjlist()
    {
    map<string,Proj ect*>::iterator ii;

    for(ii=prjlists .begin();ii!=pr jlists.end();ii ++)
    {
    cout << "Project Name: " << ii->first << "\n "<<endl;
    }
    }

    /////////////////////////////////////////////////////////////////////////////
    Project.h
    #ifndef _PROJECT_H
    #define _PROJECT_H

    #include <string>
    #include "SetupManager.h "
    #include "PrjError.h "

    using namespace std;

    class Project{
    public:
    Project();
    Project(const Project &prj);
    ~Project();

    inline string GetPrjName(){re turn prjname;}
    inline void SetPrjName(cons t string &name){prjname= name;}



    inline string GetCadName(){re turn cadname;}
    inline void SetCadName(cons t string name){cadname=n ame;}

    inline void SetSetupmanager (SetupManager& mag){setup=mag; }

    inline void GetSetupmanager (SetupManager &mag){mag=setup ;}


    protected:
    string prjname;
    //cad name
    string cadname;

    SetupManager setup;

    };


    #endif

    Project.cpp
    #include "Project.h"

    Project::Projec t()
    {
    prjname="";
    cadname="";

    }

    Project::Projec t(const Project &prj)
    {
    prjname=prj.prj name;

    cadname=prj.cad name;
    setup=prj.setup ;

    }

    Project::~Proje ct()
    {
    }

    //////////////////////////////////////////////////////////
    Setup.h
    #ifndef _SETUP_H
    #define _SETUP_H

    #include <string>
    #include <list>
    #include "Machine.h"
    #include "Fixture.h"
    //#include "Orientatio n.h"

    using namespace std;

    class Setup
    {

    protected:
    string setupname;

    Machine machineinfo;
    Fixture fixtureinfo;
    list<stringwill faces;
    list<stringfini shedfaces;

    public:

    Setup();
    Setup(const Setup&setup);
    // ~Setup();
    //for operator =
    Setup& operator=(const Setup &it);

    inline string GetSetupname(){ return setupname;}
    inline void SetSetupname(co nst string &name){setupnam e=name;}
    inline void GetMachine(Mach ine &mac){mac=machi neinfo;}
    inline void SetMachine(Mach ine &machine){machi neinfo=machine; }
    inline void GetFixture(Fixt ure &fix){fix=fixtu reinfo;}
    inline void SetFixture( Fixture &fix){fixturein fo=fix;}
    inline void GetFinishedface s(list<string&f inish)
    {finish=finishe dfaces;}
    // inline void SetFinishedface s(list<string&f eature)
    {finishedfaces= feature;}
    inline void GetWillfaces(li st<string&will) {will=willfaces ;}
    // inline void SetWillfaces(li st<string&will) {willfaces=will ;}

    void AddWillFace(con st string &face);
    void AddFinishedFace (const string &face);

    void DeleteWillFace( const string &face);
    void DeleteFinishedF ace(const string &face);

    void RenameWillFace( const string &oldface,con st string &newface);
    void RenameFinishedF ace(const string &oldface,con st string &newface);
    };


    #endif

    Setup.cpp
    #include "Setup.h"
    #include "PrjError.h "
    #include <algorithm>

    Setup::Setup()
    {
    setupname="";
    }
    Setup::Setup(co nst Setup &setup)
    {
    finishedfaces=s etup.finishedfa ces;
    fixtureinfo=set up.fixtureinfo;
    machineinfo=set up.machineinfo;
    // orient=setup.or ient;
    willfaces=setup .willfaces;

    }

    Setup& Setup::operator =(const Setup &it)
    {
    if(this!=&it)
    {
    this->finishedfaces= it.finishedface s;
    this->willfaces=it.w illfaces;
    this->fixtureinfo=it .fixtureinfo;
    this->machineinfo=it .machineinfo;
    }
    return *this;
    }


    Setup::~Setup()
    {
    /* willfaces.erase (willfaces.begi n(),willfaces.e nd());
    finishedfaces.e rase(finishedfa ces.begin(),fin ishedfaces.end( ));*/
    }

    void Setup::AddFinis hedFace(const string &face)
    {
    list<string>::i terator ii;

    ii=find(finishe dfaces.begin(), finishedfaces.e nd(),face);


    if(ii!=finished faces.end())
    throw PrjError::PrjEr ror(PrjError::E RR_ALREADY_EXIS T);
    finishedfaces.p ush_back(face);
    }

    void Setup::AddWillF ace(const string &face)
    {
    list<string>::i terator ii;
    ii=find(willfac es.begin(),will faces.end(),fac e);

    if(ii!=willface s.end())
    throw PrjError::PrjEr ror(PrjError::E RR_ALREADY_EXIS T);
    willfaces.push_ back(face);
    }

    void Setup::DeleteFi nishedFace(cons t string &face)
    {
    list<string>::i terator ii;
    ii=find(finishe dfaces.begin(), finishedfaces.e nd(),face);
    if(ii==finished faces.end())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    finishedfaces.e rase(ii);
    }

    void Setup::DeleteWi llFace(const string &face)
    {
    list<string>::i terator ii;
    ii=find(willfac es.begin(),will faces.end(),fac e);
    if(ii==willface s.end())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    willfaces.erase (ii);
    }

    void Setup::RenameFi nishedFace(cons t string &oldface,con st string
    &newface)
    {
    list<string>::i terator ii;
    ii=find(finishe dfaces.begin(), finishedfaces.e nd(),oldface);
    if(ii==finished faces.end())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);

    *ii=newface;
    }

    void Setup::RenameWi llFace(const string &oldface,con st string
    &newface)
    {
    list<string>::i terator ii;
    ii=find(willfac es.begin(),will faces.end(),old face);
    if(ii==willface s.end())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    *ii=newface;
    }


    ///////////////////////////////////////////////////////////////////////////////////////////////
    SetupManager.h
    #ifndef _SETUPMANAGER_H
    #define _SETUPMANAGER_H

    #include <string>
    #include <map>
    #include "Setup.h"
    using namespace std;
    class SetupManager
    {
    protected:
    map<string,Setu p*setuplists;
    Setup *currentSetup;
    string currentSetupId;

    public:
    SetupManager();
    SetupManager(co nst SetupManager& mag);
    ~SetupManager() ;
    void AddSetup(const Setup &setup,const string &setupname);
    void DeleteSetup(con st string &setupname);
    void RenameSetup(con st string &oldname,con st string &newname);
    inline string GetCurrentSetup (){return currentSetupId; }
    void SetCurrentSetup (const string &setupname);

    //remap
    template<class Map, typename Key>
    bool remap(Map& map, Key const& oldKey, Key const& newKey)
    {

    Map::iterator const oldPos = map.find( oldKey );
    if( oldPos == map.end() )
    return false;
    std::pair<Map:: iterator,boolin sInfo
    = map.insert( Map::value_type (newKey, oldPos->second) );
    if( insInfo.second == false ) // new key already exists -not
    added
    return (insInfo.first= =oldPos); //-true if both keys
    equivalent
    // NOTE: if the two keys are equivalent for the map without
    actually
    // being identical, the value of the key is not changed.
    std::swap( oldPos->second, insInfo.first->second ); //move value
    map.erase( oldPos );
    return true;
    }

    //this is only used for test
    // void GetSetupmanager ();


    };

    #endif

    SetupManager.cp p
    #include "SetupManager.h "
    #include "Machine.h"
    #include "Setup.h"
    #include "PrjError.h "
    #include "Fixture.h"
    #include <iostream>

    SetupManager::S etupManager()
    {
    currentSetupId= "";
    }
    SetupManager::S etupManager(con st SetupManager &mag)
    {
    currentSetupId= mag.currentSetu pId;
    currentSetup=ma g.currentSetup;
    setuplists=mag. setuplists;
    }
    SetupManager::~ SetupManager()
    {

    map<string,Setu p*>::iterator ii;
    for(ii=setuplis ts.begin();ii!= setuplists.end( );++ii)
    delete(ii->second);
    setuplists.clea r();
    /* map<string,Setu p*>::iterator begin,end;
    begin=++setupli sts.begin();
    end=--setuplists.end( );
    setuplists.eras e(begin,end);*/

    }

    void SetupManager::A ddSetup(const Setup &setup,const string
    &setupname)
    {
    map<string,Setu p*>::iterator ii;

    Setup *newSetup=NULL;

    if(setupname.le ngth()==0)
    throw PrjError::PrjEr ror(PrjError::E RR_BAD_SETUPNAM E);

    ii=setuplists.f ind(setupname);

    if(ii==setuplis ts.end())
    {
    newSetup=new Setup(setup);
    setuplists[setupname]=newSetup;
    }
    else
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);

    }




    void SetupManager::D eleteSetup(cons t string& setupname)
    {
    map<string,Setu p*>::iterator ii;
    ii=setuplists.f ind(setupname);
    if(ii==setuplis ts.end())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    delete(ii->second);
    setuplists.eras e(ii);
    }

    void SetupManager::R enameSetup(cons t string& oldname,const string
    &newname)
    {
    map<string,Setu p*>::iterator ii;
    if(newname.leng th()==0)
    throw PrjError::PrjEr ror(PrjError::E RR_BAD_SETUPNAM E);
    ii=setuplists.f ind(oldname);
    if(ii==setuplis ts.end())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    // (*ii).first=new name;
    this->remap<map<stri ng,Setup*>,stri ng(setuplists,o ldname,newname) ;


    }

    void SetupManager::S etCurrentSetup( const string &setupname)
    {
    map<string,Setu p*>::iterator ii;
    if(setupname.le ngth()==0)
    throw PrjError::PrjEr ror(PrjError::E RR_BAD_SETUPNAM E);
    else if(setupname!=c urrentSetupId)
    {
    ii=setuplists.f ind(setupname);
    if(ii==setuplis ts.end())
    throw PrjError::PrjEr ror(PrjError::E RR_NOT_FIND);
    currentSetupId= setupname;
    currentSetup=ii->second;
    }
    }

    /////////////////////////////////////////////////////////////////////////////////////

    Ugoperation.h
    #ifndef _UGOPERATION_H
    #define _UGOPERATION_H

    #include <string>
    using namespace std;

    class Ugoperation
    {
    protected:
    string faceId;
    string pointId;
    string locatorId;
    string cadname;

    public:

    void Ug_opencad(cons t string &name);
    void Ug_getface();
    void Ug_getpoint();
    void Ug_getlocator() ;

    inline void Ug_setfaceid(co nst string &id){faceId=id; }
    inline string Ug_getfaceid(){ return faceId;}
    inline void Ug_setpointid(c onst string &id){pointId=id ;}
    inline string Ug_getpointid() {return pointId;}
    inline void Ug_setlocatorid (const string &id){locatorId= id;}
    inline string Ug_getlocatorid (){return locatorId;}
    };


    #endif

    Ugoperation.cpp
    #include "Ugoperatio n.h"
    #include<iostre am>
    #include<sstrea m>

    int testface=10;
    int testpoint=100;
    int testlocator=100 0;
    string cadname("c:/test.prt");

    void Ugoperation::Ug _getface()
    {
    //here is only for test,later should add some ug api functions
    stringstream s;
    testface+=1;
    s << testface;

    faceId=s.str();
    }

    void Ugoperation::Ug _getpoint()
    {
    //here is only for test
    stringstream s;
    testpoint+=1;
    s<<testpoint;

    pointId=s.str() ;
    }

    void Ugoperation::Ug _getlocator()
    {
    stringstream s;
    testlocator+=1;
    s << testlocator;

    locatorId=s.str ();
    }


    void Ugoperation::Ug _opencad(const string &name)
    {
    //only for test

    cadname=name;
    }

    /////////////////////////////////////////////////////////////////////////////////////////
    testmain.cpp
    #include "PrjManager .h"
    #include "Project.h"
    #include "PrjError.h "
    #include "Setup.h"
    #include "Ugoperatio n.h"
    #include "Fixture.h"
    #include "Machine.h"
    #include "SetupManager.h "

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

    int main()
    {
    PrjManager prjmanager;
    Ugoperation op;
    Fixture fix;
    Machine mac;
    Setup setup;
    SetupManager setupmag;

    // vector<stringpf aces;

    string macname("Machin e1");

    Project prj;
    // Project prj2;

    string facename[3];
    string pointname[6];
    string locator[6];

    //suppose get three faces
    op.Ug_getface() ;
    facename[0]=op.Ug_getfacei d();
    op.Ug_getface() ;
    facename[1]=op.Ug_getfacei d();
    op.Ug_getface() ;
    facename[2]=op.Ug_getfacei d();

    //get six points
    for(int i=0;i<6;i++)
    {
    op.Ug_getpoint( );
    pointname[i]=op.Ug_getpoint id();
    op.Ug_getlocato r();
    locator[i]=op.Ug_getlocat orid();
    }

    for(int i=0;i<3;i++)
    {
    fix.AddLocateFa ce(facename[i]);

    }

    // fix.GetFacesFro mVector(pfaces) ;


    for(int j=0;j<6;j++)
    {
    if(j<3)
    fix.AddLocatePo int(facename[0],pointname[j]);
    if(j>2 && j<5)
    fix.AddLocatePo int(facename[1],pointname[j]);
    if(j==5)
    fix.AddLocatePo int(facename[2],pointname[j]);
    }

    for(int j=0;j<6;j++)
    {
    fix.AddLocator( pointname[j],locator[j]);
    }

    setup.SetFixtur e(fix);

    //add machine info
    mac.SetMachinen ame(macname);

    setup.SetMachin e(mac);


    //add will faces and finished faces, here is only for test
    list<stringwill ;
    list<stringfini sh;

    string willface[2]={"001","002" };
    string finishedface[4]={"003","004"," 005","006"};
    for(int i=0;i<4;i++)
    {
    setup.AddFinish edFace(finished face[i]);
    }
    for(int i=0;i<2;i++)
    setup.AddWillFa ce(willface[i]);


    //to deal with setup manager
    setupmag.AddSet up(setup,"setup 1");

    setupmag.SetCur rentSetup("setu p1");

    // setupmag.GetSet upmanager();

    prj.SetSetupman ager(setupmag);

    // prj.SetPrjName( "projetct 1");

    prjmanager.AddP rj(prj,"project 1");
    return 0;

    }

  • Phlip

    #2
    Re: why destructor function called twice

    David wrote:
    something wrong with my code, it seems that the destructor function
    has been called twice. I don't know why.here is my codes
    Tip: Keep pulling lines, functions, and classes out of that until it
    reproduces the bug in the minimum lines possible.

    Only then post the sample code.

    But that tip runs the risk of exposing the bug for you...

    --
    Phlip
    http://www.greencheese.us/ZeekLand <-- NOT a blog!!!


    Comment

    • red floyd

      #3
      Re: why destructor function called twice

      David wrote:
      Hi all,
      something wrong with my code, it seems that the destructor function
      has been called twice. I don't know why.here is my codes
      Fixture.h
      #ifndef _FIXTURE_H
      #define _FIXTURE_H
      [remainder redacted]
      This is most likely not the cause of your problem, but your program is
      ill-formed.

      Any identifier with a leading underscore followed by an uppercase letter
      is reserved to the implementation -- you may not use it for your own
      purposes.

      Comment

      • Ron Natalie

        #4
        Re: why destructor function called twice

        David wrote:
        Hi all,
        something wrong with my code, it seems that the destructor function
        has been called twice. I don't know why.here is my codes
        Fixture.h
        >\
        Your code is too large for any sane person to want to diagnose.
        Cut it down.

        Without bothering to look to carefully, absent any explicit
        destructor calls, my guess is that your destructor IS NOT
        being called twice, but in fact you're missing the fact that
        a temporary object is being constructed somewhere and you're
        seeing that object being destructed.

        Check all your copy-assignment operatosr and copy constructors
        for proper operation. Remember things are put into and moved
        around standard containers by copying.

        I note specifically that you are violating the "rule of three."
        While you have copy constructors and destuctors, your classes
        lack a definition of an assignment operator. This is particularly
        bad since you use assignment all over the place in your code.

        Comment

        • Ralph D. Ungermann

          #5
          Re: why destructor function called twice

          David wrote:
          Hi all,
          something wrong with my code, it seems that the destructor function
          has been called twice. I don't know why.here is my codes
          Do you mean Fixture::~Fixtu re() ? Then there is nothing wrong with your
          code: you have two such objects.



          class Setup
          {
          protected:
          Fixture fixtureinfo;
          int main()
          {
          Fixture fix;
          Setup setup;

          Comment

          Working...