Constructor not called if a default param is supplied?

Started by
16 comments, last by Zahlman 18 years, 10 months ago
Ok, my question is simple: is the constructor for a class not called if it has a default parameter? I have a class:

namespace dftCommon
{
    class StateMachine
    {
        Value*            m_pStates;
        unsigned int    m_nCount;
    public:
        StateMachine(unsigned int nStateCount = 16); // Fixed
        ~StateMachine();
        
        void    SetState(unsigned int nIndex, Value NewState);
        Value    GetState(unsigned int nIndex);
        void    SaveStates(Value* pStates, unsigned int nCount);
        void    LoadStates(const Value* pStates, unsigned int nCount);
    };
}




dftCommon::StateMachine::StateMachine(unsigned int nStateCount)
{
    assert(nStateCount > 1);
    m_pStates    = new Value[nStateCount];
    m_nCount    = nStateCount;
    memset(&m_pStates, 0, nStateCount);
}

dftCommon::StateMachine::~StateMachine()
{
    delete m_pStates;
    m_nCount = 0;
}

void dftCommon::StateMachine::SetState(unsigned int nIndex, Value NewState)
{
    assert(nIndex < m_nCount);
    m_pStates[nIndex] = NewState;
}

dftCommon::Value dftCommon::StateMachine::GetState(unsigned int nIndex)
{
    assert(nIndex < m_nCount);
    return m_pStates[nIndex];
    return 0;
}

void dftCommon::StateMachine::SaveStates(dftCommon::Value* pStates, unsigned int nCount)
{
    assert(pStates != 0);
    
    // We only have enough states for an m_nCount, so we'll only fill that many.
    if(nCount > m_nCount)
        nCount = m_nCount;
    
    for(unsigned int nIndex = 0; nIndex < nCount; ++nIndex)
        pStates[nIndex] = m_pStates[nIndex];
}

void dftCommon::StateMachine::LoadStates(const dftCommon::Value* pStates, unsigned int nCount)
{
    assert(pStates != 0);
    
    // We only have enough room for m_nCount states, so we'll only get that many.
    if(nCount > m_nCount)
        nCount = m_nCount;
    
    for(unsigned int nIndex = 0; nIndex < m_nCount; ++nIndex)
        m_pStates[nIndex] = pStates[nIndex];
}




enum TEST_STATES { TEST_TITLE = 0 };

dftCommon::StateMachine g_StateMachine;
g_StateMachine.SetState(TEST_TITLE, "StateMachine Test");
I've stepped through it with my debugger, but the constructor code is never called. Did I miss something or is this a bug with MSVC++ 6? It stops on line 19 (the assertion in dftCommon::StateMachine::SetState().) [Edited by - Programmer16 on June 23, 2005 12:58:00 AM]
Advertisement
try calling the constructor you created instead of the default one:

dftCommon::StateMachine g_StateMachine(1024);g_StateMachine.SetState(TEST_TITLE, "StateMachine Test");


I am not sure whether or not a default constructor with no arguments that does nothing gets created for you, or if all that happens is that the memory for your object gets allocated, but either way, your constructor will never get called if you dont provide the required arguments.
I guess I should've figured that it would call the default constructor instead of the one with the default parameter. Thanks!

Edit:
Okay, I've changed it to this:
dftCommon::StateMachine g_StateMachine(16);

And my constructor is still not getting called.

I'm not getting any errors, warnings, nothing. And it goes to SetState() correctly.

Edit 2:
Okay, I was trying to run to cursor, but that didn't work so I put a breakpoint in my constructor. It gets called, I stepped through it and all of the data and everything was created correctly. I then did run to cursor in SetState(), but by then m_nCount is 0 somehow.

Edit 3:
Okay I fixed it. I've never used memset() before and I was calling memset(&m_pStates, 0, nStates); (similiar to ZeroMemory()).

[Edited by - Programmer16 on June 22, 2005 9:17:18 PM]
You know, it would probably be wise to keep nStateCount on a member variable, to check for bounds and such and for walking the array if needed.

Or you could use a std::vector instead, or even better a std::stack, since it's a state machine.
That code shouldn't compile - perhaps you are debugging an old executable?
If you declare a non-default ctor, it hides the default ctor unless you explicitly add it.

dftCommon::StateMachine g_StateMachine;

...should fail.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Quote:Original post by Shannon Barber
That code shouldn't compile - perhaps you are debugging an old executable?
If you declare a non-default ctor, it hides the default ctor unless you explicitly add it.

dftCommon::StateMachine g_StateMachine;

...should fail.


No, this is code I wrote today. I thought that it should fail too, but maybe its just a bug in VC++ 6 or something. But I thought it would call the constructor since I supplied a default value for nStateCount.

@Kwizatz: I do store the number of states: m_nCount. I also do bounds checking (assert(nCount < m_nCount); etc.)

Anyway, I've done away with this code (sent it to the archive), since I've decided that its not needed. Thanks for the help guys.
maybe i'm blind, but where is the default value you talk about?
Perhaps you copied an old version?
As written you never supplied the default value.
"I turned into a driveway I thought was mine and crashed into a tree I don't have."- a real insurance claim
Why don't you use the debbuger and step into
dftCommon::StateMachine g_StateMachine(16);
to see what gets called.
Quote:Original post by Amnesty
maybe i'm blind, but where is the default value you talk about?
Perhaps you copied an old version?
As written you never supplied the default value.


Oops, I posted the code after I removed it. I did have a default value of 16.

Quote:STLDude
Why don't you use the debbuger and step into
dftCommon::StateMachine g_StateMachine(16);
to see what gets called.


Quote:Programmer16
I've stepped through it with my debugger, but the constructor code is never called. Did I miss something or is this a bug with MSVC++ 6? It stops on line 19 (the assertion in dftCommon::StateMachine::SetState().)


Quote:Programmer16
Okay, I was trying to run to cursor, but that didn't work so I put a breakpoint in my constructor. It gets called, I stepped through it and all of the data and everything was created correctly. I then did run to cursor in SetState(), but by then m_nCount is 0 somehow.


Okay guys, I figured out the problem. I was using memset() (instead of ZeroMemory(), which I usually use) incorrectly.

Thanks for the help!
memset and ZeroMemory, and everything else along similar lines, are dangerous things to be using with class instances (only really acceptable with POD-types, and even then, usually needlessly tricky). Just write a proper default ctor for Value instead; it will be called for each instance when the array is allocated. Better yet, use std::vector which among its other benefits is also able to separate memory allocation from instance initialization, and will keep things running smoothly and efficiently for you behind the scenes :)

This topic is closed to new replies.

Advertisement