2

Ive been staring at my code and I can't figure out why on earth my constructor is not gettign called.

It's just ignoring my constructor completely (i've check with stepping with debugger).

Here's my testapp:

using namespace MyEngine;

int _tmain(int argc, _TCHAR* argv[])
{
    TestManager* testMgr = new TestManager();
    testMgr->RunAllTests();

    delete testMgr;

    getchar();
    return 0;
}

TestManager.h:

namespace MyEngine
{

    class TestManager 
    {
    public:
        TestManager();
        TestManager(uint64_t RepeatTimes);
        ~TestManager();

        bool RunAllTests();

        bool RunMemoryTests();

    private:
        Engine* mEngine;
        ILogManager* mLogger;

        MemoryTestManager* mMemTestMgr;
        uint64_t mRepeatTimes;

    };

}

and TestManager.cpp

namespace MyEngine
{

    TestManager::TestManager()
    {
        TestManager(1);
    }

    TestManager::TestManager(uint64_t RepeatTimes)
    {
        if (RepeatTimes>0)
            mRepeatTimes = RepeatTimes;
        else 
        {
            mRepeatTimes = 1;
        }

        mEngine = Engine::GetEngine();
        mMemTestMgr = new MemoryTestManager();
    }

    TestManager::~TestManager()
    {

    }


    /* Runs all testing modules */
    bool TestManager::RunAllTests()
    {
        bool res = true;

        /* Init Engine */
        if(mEngine->Init(0,0,0))
        {
            res = true;
            res && mEngine->GetRenderManager()->Init();
            res && mLogger->Init(true,true);
            res && mEngine->GetMemoryManager()->Init(false);

        }
        else
            return false;

        /* Start Engine */
        mEngine->Start();

        /* Get logger */
        mLogger = mEngine->GetLogger();

        /* Run Memory Tests */
        res &= RunMemoryTests();

        if (res)
            mLogger->LogInfo("TEST: TESTING SUCCESSFULL");
        else
            mLogger->LogError("TEST: TESTING FAILED");

        return res;
    }

    /* Runs all memory tests */
    bool TestManager::RunMemoryTests()
    {
        bool res = true;

        res &= mMemTestMgr->AllocateTest();
        res &= mMemTestMgr->ReferenceTest();

        if (res)
            mLogger->LogInfo("TEST: RunMemoryTests SUCCESSFULL");
        else
            mLogger->LogError("TEST: RunMemoryTests FAILED");

        return res;
    }

}
jleahy
  • 16,149
  • 6
  • 47
  • 66
KaiserJohaan
  • 9,028
  • 20
  • 112
  • 199
  • What are you talking about - your constructor *is* getting called. It might just not do what you were hoping for. – Kerrek SB Feb 18 '12 at 13:31
  • What you mean to say is possibly `TestManager() : TestManager(1) { }`, although delegating constructors are not yet widely supported by contemporary compilers. – Kerrek SB Feb 18 '12 at 13:32

4 Answers4

5

You cant call another constructor from the same class. I'd refactor the init code into a separate method and call it from both constructors:

namespace MyEngine
{

    TestManager::TestManager()
    {
        Init(1);
    }

    TestManager::TestManager(uint64_t RepeatTimes)
    {
        Init(RepeatTimes);
    }

    void TestManager::Init(uint64_t RepeatTimes)
    {
        if (RepeatTimes>0)
            mRepeatTimes = RepeatTimes;
        else 
        {
            mRepeatTimes = 1;
        }

        mEngine = Engine::GetEngine();
        mMemTestMgr = new MemoryTestManager();
    }
}
rtn
  • 127,556
  • 20
  • 111
  • 121
  • 3
    Well, you *can*, but it's a different syntax, and it's a new feature in C++11 ("delegating constructors"). – Kerrek SB Feb 18 '12 at 13:33
  • Well, you can, but it doesn't do what you want. What that call does is create a new object that is promptly deleted, with no effect on the original object. – ibid Feb 18 '12 at 13:33
  • @KaiserJohaan well, C++11 has you covered [same question](http://stackoverflow.com/questions/308276/c-call-constructor-from-constructor) . `TestManager():TestManager(1);` but I think it has to be in the declaration. – PeterT Feb 18 '12 at 13:35
3

When you call TestManager(1); inside your TestManager::TestManager() constructor, you're creating another instance of TestManager, using the constructor TestManager::TestManager(uint64_t).

You can't do this on C++, you have to create either a init method, were you set the instance variables to whatever you want, or use optional parameters:

TestManager(uint64_t RepeatTimes = 0);

Then, if you create an instance of TestManager without arguments, you will be calling the TestManager::TestManager(uint64_t)constructor with 0 as the uint64_t argument.

mfontanini
  • 21,410
  • 4
  • 65
  • 73
0

you can't call a default constructor from a overloaded constructor. Why don't you simply create you object like this:

TestManager* testMgr = new TestManager(1);
Ebad Masood
  • 2,389
  • 28
  • 46
0

Using a default argument (as per fontanini's answer) will do what you want in this case.

But if this is a simplified example and you really do want to delegate to another constructor, then that's not possible in C++03 - the line TestManager(1) just constructs a temporary object which goes unused (and the line will probably be optimized out unless the TestManager(uint64_t) constructor has side effects).

However, you can do what you're aiming for here with a C++11 compiler and the following syntax:

TestManager::TestManager() :
    TestManager(1)
{
}
je4d
  • 7,628
  • 32
  • 46