clarification - calling virtual function from destructor

J

james

Every class is better has own constructor and deconstructor itself, even if
compiler allow you do that. Class A func1 alway be called In your code. I
revised your code for you. every class will call func1 itself. then you
don't need to name"virturl" in class B.
class A
{
public:
virtual void Func1()
{
printf("this is class A");
};
void Func1Caller()
{
Func1();
}
~A()
{
Func1Caller();
}
};

class B : public A
{
public:
B();
~B();
void Func1(){ printf("this is class B\n");}
B::B() {}
B::~B(){ Func1Caller();}
};

int main()

{
B t;
return 0;
}
 
J

james

another example is more clear about virtual function
declareation is as yours
B mean;
A meam1;
B *meam2;
meam2=&meam1;
meam2->Func1(); // callB::Func1();
meam2=&A;
meam2->Func1(); //call A::Func1();
 
J

james

I talked about virtual function, so it is not serious for formal porgram,
anyway thanks a lot
 
J

james

then I agree with Sharard Kala' opion. It is a bed idea to put virtual
function in destructor. see my another example at previou post.
 
L

lallous

Hello


class A

{

public:

virtual void Func1() = 0;

void Func1Caller()

{

Func1();

}

~A()

{

Func1Caller();

}

};

class B : public A

{

public:

virtual void Func1()

{

printf("this is func1\n");

}

};

int main()

{

B t;

return 0;

}



It seems that VC is not allowing Func1Caller() to call Func1() from the
destructor.
Don't know if this a C++ issue or a compiler issue.

Can someone clarify and provide a workaround?
 
A

Alf P. Steinbach

class A
{
public:
virtual void Func1() = 0;
void Func1Caller()
{
Func1();
}
~A()
{
Func1Caller();
}
};

The destructor here has undefined behavior because it's calling
a pure virtual function.

With a good C++ compiler this will cause a run-time error, but
formally it could do anything (including seemingly "working").

Hint: get your indentation in order before worrying about such
things, and also see the FAQ, which answers such questions.
 
L

lallous

Alf P. Steinbach said:
The destructor here has undefined behavior because it's calling
a pure virtual function.
But isn't the pure virtual function defined through class B?

And you cannot create an instance of class A unless its pure virtual method
is defined.
With a good C++ compiler this will cause a run-time error, but
formally it could do anything (including seemingly "working").
It did produce a runtime error.
Hint: get your indentation in order before worrying about such
things, and also see the FAQ, which answers such questions.
The code is idented, but the NG composer got it unidented.

I read C++ Lite FAQ but didn't know how to solve.
 
L

lilburne

lallous said:
But isn't the pure virtual function defined through class B?

And you cannot create an instance of class A unless its pure virtual method
is defined.

When you enter A's destructor B has already been destroyed, it is no
more, it is an ex-B.
 
S

Sharad Kala

james said:
Every class is better has own constructor and deconstructor itself, even if
compiler allow you do that. Class A func1 alway be called In your code. I
revised your code for you. every class will call func1 itself. then you
don't need to name"virturl" in class B.
class A
{
public:
virtual void Func1()
{
printf("this is class A");
};
void Func1Caller()
{
Func1();
}
~A()
{
Func1Caller();
}
};

class B : public A
{
public:
B();
~B();
void Func1(){ printf("this is class B\n");}
B::B() {}
B::~B(){ Func1Caller();}
};

int main()

{
B t;
return 0;
}


The code you posted won't even compile dear friend!
As pointed by others calling pure virtual function inside a destructor is
calling in for undefined behavior.
 
M

Martijn Lievaart

It seems that VC is not allowing Func1Caller() to call Func1() from the
destructor.
Don't know if this a C++ issue or a compiler issue.

Can someone clarify and provide a workaround?

It's normal C++ behaviour. At the time of the destructor (the same goes
for the constrctor) the dynamic type is set to that of the destructor.
What does that mean?

class A
{
public:
virtual f1() { puts("A"); }
};

class B
{
public:
virtual f1() { puts("B"); }
~B()
{
f1(); // Prints B, we are a B, we are no longer a C
A *p = this;
p->f1(); // Again prints B, virtual functions still work,
// we are a B, so calls B::f1
}
};

class C
{
public:
virtual f1() { puts("C"); }
};

int main();
{
C c;
}

When C gets destroyed, first the destuctor for C is executed, then the
destructor for the B subobject *but* with it's type set to B, then the A
subobject is destroyed, but with it's type set to A.

Think about it. The C object is already destroyed, it would make a fine
mess if virtual functions worked the way you assumed they do.

HTH,
M4
 
R

red floyd

lilburne said:
When you enter A's destructor B has already been destroyed, it is no
more, it is an ex-B.

It has ceased to "B"? Of course, it could just be pining for the fjords.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top