Click here to Skip to main content
15,885,920 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
QuestionSerial Port OK in class constructor but not outside... Pin
Mike Grove23-Jul-13 5:49
Mike Grove23-Jul-13 5:49 
AnswerRe: Serial Port OK in class constructor but not outside... Pin
Jochen Arndt23-Jul-13 6:23
professionalJochen Arndt23-Jul-13 6:23 
GeneralRe: Serial Port OK in class constructor but not outside... Pin
Mike Grove23-Jul-13 22:11
Mike Grove23-Jul-13 22:11 
AnswerRe: Serial Port OK in class constructor but not outside... Pin
etkid8423-Jul-13 8:53
etkid8423-Jul-13 8:53 
GeneralRe: Serial Port OK in class constructor but not outside... Pin
Mike Grove23-Jul-13 22:13
Mike Grove23-Jul-13 22:13 
AnswerRe: Serial Port OK in class constructor but not outside... Pin
pasztorpisti23-Jul-13 9:16
pasztorpisti23-Jul-13 9:16 
GeneralRe: Serial Port OK in class constructor but not outside... Pin
Richard Andrew x6423-Jul-13 13:31
professionalRichard Andrew x6423-Jul-13 13:31 
GeneralRe: Serial Port OK in class constructor but not outside... Pin
pasztorpisti24-Jul-13 1:03
pasztorpisti24-Jul-13 1:03 
EDIT: previously I stated this has something to do with the closed world asssumptions of the compiler but I'm not sure about that. This thing works this way: It has no point to call the virtual method of a derived class whose constructor hasn't yet been executed because that virtual method would have access to uninitiailized members. In java and C# such virtual call calls the derived virtual method in contrast to C++!!!! But there at least the derived class members are already zero initialized, still, that is also the source of evil bugs! I had the luck to fix one such bug in java. Then why doesn't the compiler tell me about direct/indirect virtual calls from my ctor/dtor??? Because it can't always do that and even in some cases where it could tell it doesn't do that, probably the compiler writers didn't want to waste time on that or maybe this is the intended behavior even if its useless and often the source of bugs.

The code of the constructor of each c++ class looks like the following (Derived1 inherits from Base, Derived2 inherits from Derived1:
C++
Base::Base()
{
    auto generated: vtable = Base::vtable
    <your ctor code here>
}

Derived1::Derived1()
{
    auto generated: call Base::Base
    auto generated: vtable = Derived1::vtable
    <your ctor code here>
}

Derived2::Derived2()
{
    auto generated: call Derived1::Derived1
    auto generated: vtable = Derived2::vtable
    <your ctor code here>
}


The destructors:
C++
Base::~Base()
{
    auto generated: vtable = Base::vtable
    <your dtor code here>
}

Derived1::~Derived1()
{
    auto generated: vtable = Derived1::vtable
    <your ctor code here>
    auto generated: call Base::~Base
}

Derived2::~Derived2()
{
    auto generated: vtable = Derived2::vtable
    <your ctor code here>
    auto generated: call Derived1::~Derived1
}


With the above info guess what will be printed by this example program:
C++
class Base
{
public:
    Base()
    {
        VirtualCall();
    }
    ~Base()
    {
        VirtualCall();
    }

    virtual void VirtualCall()
    {
        printf("Base::VirtualCall()\n");
    }
};

class Derived : public Base
{
public:
    virtual void VirtualCall()
    {
        printf("Derived::VirtualCall()\n");
    }
};

void TestFunc()
{
    Derived* d = new Derived;
    delete d;
}


You should never do complex initialization and deinitialization in your ctor/dtor because the virtual call may be hidden inside non-virtual function calls several call deep. Or worse, when you write the ctor/dtor code it works well but someone introduces a virtual call into a non-virtual method later and this makes your ctor/dtor buggy. For this reason all I do in the ctor is filling the member vars with default values and in the dtor I just release resources held by member vars.
Indirect virtual func call with the same result as the above buggy code:
C++
class Base
{
public:
    Base()
    {
        IndirectVirtualCallFromCtorDtor();
    }
    ~Base()
    {
        IndirectVirtualCallFromCtorDtor();
    }


    void IndirectVirtualCallFromCtorDtor()
    {
        VirtualCall();
    }

    virtual void VirtualCall()
    {
        printf("Base::VirtualCall()\n");
    }
};

class Derived : public Base
{
public:
    virtual void VirtualCall()
    {
        printf("Derived::VirtualCall()\n");
    }
};

void TestFunc()
{
    Derived* d = new Derived;
    delete d;
}


An even worse case that results in a "runtime error: pure virtual function call":
C++
class Base;
static void HelperFunc(Base* b);

class Base
{
public:
    Base()
    {
        // comment out this call if you want to try the destructor
        HelperFunc(this);
    }
    ~Base()
    {
        HelperFunc(this);
    }

    virtual void VirtualCall() = 0;
};

static void HelperFunc(Base* b)
{
    // This function doesn't know that b is half constructed or half destructed
    b->VirtualCall();

}


class Derived : public Base
{
public:
    virtual void VirtualCall()
    {
        printf("Derived::VirtualCall()\n");
    }
};

void TestFunc()
{
    Derived* d = new Derived;
    delete d;
}

GeneralRe: Serial Port OK in class constructor but not outside... Pin
Richard Andrew x6424-Jul-13 14:03
professionalRichard Andrew x6424-Jul-13 14:03 
GeneralRe: Serial Port OK in class constructor but not outside... Pin
pasztorpisti24-Jul-13 14:17
pasztorpisti24-Jul-13 14:17 
QuestionInitilazation error in MFC C++ App Pin
ForNow23-Jul-13 5:16
ForNow23-Jul-13 5:16 
SuggestionRe: Initilazation error in MFC C++ App Pin
Richard MacCutchan23-Jul-13 5:31
mveRichard MacCutchan23-Jul-13 5:31 
GeneralRe: Initilazation error in MFC C++ App Pin
ForNow23-Jul-13 6:30
ForNow23-Jul-13 6:30 
GeneralRe: Initilazation error in MFC C++ App Pin
Richard MacCutchan23-Jul-13 6:48
mveRichard MacCutchan23-Jul-13 6:48 
GeneralRe: Initilazation error in MFC C++ App Pin
ForNow23-Jul-13 8:22
ForNow23-Jul-13 8:22 
GeneralRe: Initilazation error in MFC C++ App Pin
David Crow23-Jul-13 9:11
David Crow23-Jul-13 9:11 
GeneralRe: Initilazation error in MFC C++ App Pin
ForNow26-Jul-13 5:16
ForNow26-Jul-13 5:16 
GeneralRe: Initilazation error in MFC C++ App Pin
ForNow23-Jul-13 6:32
ForNow23-Jul-13 6:32 
QuestionRe: Initilazation error in MFC C++ App Pin
David Crow23-Jul-13 9:11
David Crow23-Jul-13 9:11 
AnswerRe: Initilazation error in MFC C++ App Pin
ForNow23-Jul-13 11:01
ForNow23-Jul-13 11:01 
AnswerRe: Initilazation error in MFC C++ App Pin
Erudite_Eric29-Jul-13 0:39
Erudite_Eric29-Jul-13 0:39 
GeneralMessage Closed Pin
22-Jul-13 6:11
NaOHwwl22-Jul-13 6:11 
GeneralRe: Compiler Error Pin
R. Giskard Reventlov22-Jul-13 6:17
R. Giskard Reventlov22-Jul-13 6:17 
GeneralRe: Compiler Error Pin
Thomas Daniels22-Jul-13 6:50
mentorThomas Daniels22-Jul-13 6:50 
GeneralRe: Compiler Error Pin
R. Giskard Reventlov22-Jul-13 6:58
R. Giskard Reventlov22-Jul-13 6:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.