hello every body,
I know I shouldn't call virtual functions during construction or destruction. -
#include <iostream>
-
using namespace std;
-
-
class BaseWithPureFunction
-
{
-
public:
-
-
-
virtual void PureFunc() = 0;
-
void CallPureFunc()
-
{
-
PureFunc();
-
}
-
-
BaseWithPureFunction() ;
-
};
-
-
BaseWithPureFunction::BaseWithPureFunction()
-
{
-
/*
-
Call pure-virtual via CallPureFun.
-
Cause r6025 error.I have no question here.
-
*/
-
CallPureFunc();
-
-
}
-
-
void BaseWithPureFunction::PureFunc()
-
{
-
cout<<"Pure!"<<endl;
-
}
-
-
-
-
-
class BaseEx:public BaseWithPureFunction
-
{
-
public:
-
virtual void PureFunc()
-
{
-
printf( "BaseEx::PureFunc()\r\n ");
-
}
-
};
-
-
int _tmain(int argc, _TCHAR* argv[])
-
{
-
-
BaseEx ex;
-
-
return 0;
-
}
-
-
-
If replace the BaseWithPureFunction function : -
BaseWithPureFunction::BaseWithPureFunction()
-
{
-
/*
-
Call pure-virtual directly.
-
Running well.I puzzled.
-
-
*/
-
PureFunc();
-
-
}
-
-
I puzzled why call pure-virtual directly, the programe won't cause error.I found some explanation in "Effective C++ Item 9".But I still think that this explanation is not detailed enough.
This is your code: - struct BaseWithPureFunction
-
{
-
virtual void PureFunc() = 0;
-
-
void CallPureFunc()
-
{
-
PureFunc();
-
}
-
-
BaseWithPureFunction();
-
};
-
-
BaseWithPureFunction::BaseWithPureFunction()
-
{
-
PureFunc();//running well
-
CallPureFunc(); //error.
-
//Is there any difference between PureFunc and CallPureFunc.
-
}
When you call PureFunc(), you really are calling
BaseWithPureFunction::PureFunc() because the virtual keyword is suspended inside a constructor.
However, when you are inside CallPureFunc() you may not be inside a constructor so when you call PureFunc() the VTBL is accessed and you bomb with a run-time error about calling a pure virtual function. All you need to do is tell the compiler to call the function without using the VTBL. That is, you need to specify the complete function name: - struct BaseWithPureFunction
-
{
-
virtual void PureFunc() = 0;
-
-
void CallPureFunc()
-
{
-
BaseWithPureFunction::PureFunc();
-
}
-
-
BaseWithPureFunction();
-
};
Now you are calling the function by name directly without using the VTBL. Now the program runs correctly.
11 1980
Think about this.
When you have a virtual function, you instruct the compiler that when there is a choice between calling the base function or the derived function, the derived function is to be called.
Therefore, if you have:
class Base
{
public:
virtual void Method();
};
Think about this.
When you have a virtual function, you instruct the compiler that when there is a choice between calling the base function or the derived function, the derived function is to be called.
However, during construction there is no guarantee that the derived object has been created yet. Therefore, when the base portion of the object is created, the call goes to the base virtual function.
The reverse appplies during destruction. Since the object is destroyed in reverse order, calling a virtual function in a destirctor results in a call to the local function since the derived portion of the object may have already been destroyed.
The net result is the the virtual keyword is ignored inside constructors and destructors.
Thanks for your help.
I know during construction the base virtual function will be called.So What you said is not that I want to know.
I want to find the answer :why this part of code can go well: -
BaseWithPureFunction::BaseWithPureFunction()
-
{
-
/*
-
Call pure-virtual directly.
-
Running well.I puzzled.
-
*/
-
PureFunc();
-
}
-
In my opnion,it will cause r6025 error,too.But...
You are creating a BaseEx object.
That object inherits BaseWithPureFunction::PureFunc.
You call BaseWithPureFunction::PureFunc from a BaseEx member function.
So what's the problem?
Remember, a pure virtual function cannot be called by an object of its class but it's OK to call it from some other object.
To enforce not calling BaseWithPureFunction::PureFunc using a BaseWithPureFunction object, the compiler will not allow you to create a BaseWithPureFunction object.
But can create a BaseEx object and call BaseWithPureFunction::PureFunc usign the BaseEx object.
The fact was that I called the function of PureFunc directly and by the CallPureFunc function indirectly had different results.One is running well,but the other cause a error.Tow ways both invoked PureFunc function by the same types of 'this' pointer that pointed to base type,but they had different results.
Is there any ambiguous?
You should not be using CallWithPureFunc().
That function is a member function of the class BaseWithPureFunction and wghen you code: - BaseWithPureFunction obj;
-
obj.CallWithPurFunc();
you a compile error that you can't create an object of an abstract class because you can't use a BaseWithPureFunction object to call a pure virtual function in the BaseWithPureFunction class.
However, you can code: - BaseEx obj;
-
obj.BaseWithPureFunction::PureFunc();
to call PureFunc using a BaseEx object.
You could also: - BaseEx obj1;
-
obj1.PureFunc();
but no it's not cleas whether BaseEx::PureFunc() or BaseWithPureFunction::PureFunc() is being called unless you look in the code and see. Therefore, this is the preferred code: - BaseEx obj;
-
obj.BaseWithPureFunction::PureFunc();
Thanks again for your help.
At the point the base class constructor is invoked from the derived class constructor, the object ex is not yet of type BaseEx.The base class constructor initializes the BaseWithPureFunction subobject within ex to behave like a BaseWithPureFunction object. Therefore, when the virtual PureFunc is called in base class constructor, it binds to BaseWithPureFunction::PureFunc.According to holy,it should lead a error.But when I running this code it goes well.
So I altered BaseWithPureFunction constructor I made it invoke the BaseWithPureFunction::CallPureFunc.Then the virtual function PureFunc will be invoked by CallPureFunc.
When I running the code I have altered,a r6025 error appeared.
Two kinds of codes are both equal to using a BaseWithPureFunction object-a base object- to call a pure virtual function .
So I begin to think why two kinds of codes will lead differernt results.
The virtual keyword is suspended in constrcutors and destructors. It's like its not there.
Re-read my post #3.
...My question has been answered?May be my expression is unclear.
Please look at the question again,and make sure what I want to know.Thank you. -
#include <iostream>
-
using namespace std;
-
-
struct BaseWithPureFunction
-
{
-
virtual void PureFunc() = 0;
-
-
void CallPureFunc()
-
{
-
PureFunc();
-
}
-
-
BaseWithPureFunction();
-
};
-
-
BaseWithPureFunction::BaseWithPureFunction()
-
{
-
PureFunc();//running well
-
CallPureFunc(); //error.
-
//Is there any difference between PureFunc and CallPureFunc.
-
}
-
-
void BaseWithPureFunction::PureFunc()
-
{
-
cout << 3 << endl;
-
}
-
-
struct BaseEx : BaseWithPureFunction
-
{
-
virtual void PureFunc()
-
{
-
cout << "BaseEx::PureFunc()" << endl;
-
}
-
};
-
-
int main()
-
{
-
BaseEx ex;
-
-
return 0;
-
}
-
-
This is your code: - struct BaseWithPureFunction
-
{
-
virtual void PureFunc() = 0;
-
-
void CallPureFunc()
-
{
-
PureFunc();
-
}
-
-
BaseWithPureFunction();
-
};
-
-
BaseWithPureFunction::BaseWithPureFunction()
-
{
-
PureFunc();//running well
-
CallPureFunc(); //error.
-
//Is there any difference between PureFunc and CallPureFunc.
-
}
When you call PureFunc(), you really are calling
BaseWithPureFunction::PureFunc() because the virtual keyword is suspended inside a constructor.
However, when you are inside CallPureFunc() you may not be inside a constructor so when you call PureFunc() the VTBL is accessed and you bomb with a run-time error about calling a pure virtual function. All you need to do is tell the compiler to call the function without using the VTBL. That is, you need to specify the complete function name: - struct BaseWithPureFunction
-
{
-
virtual void PureFunc() = 0;
-
-
void CallPureFunc()
-
{
-
BaseWithPureFunction::PureFunc();
-
}
-
-
BaseWithPureFunction();
-
};
Now you are calling the function by name directly without using the VTBL. Now the program runs correctly.
I finally understand.
Thank you very much indeed .
Sign in to post your reply or Sign up for a free account.
Similar topics
by: mescaline |
last post by:
If a function is declared a virtual function, in what cases will
(some) compilers still do static binding?
thanks
|
by: Stijn Oude Brunink |
last post by:
Hello,
I have the following trade off to make:
A base class with 2 virtual functions would be realy helpfull for the
problem I'm working on. Still though the functions that my program will use...
|
by: heted7 |
last post by:
Hi,
Most of the books on C++ say something like this: "A virtual destructor
should be defined if the class contains at least one virtual member
function."
My question is: why is it only for...
|
by: marcwentink |
last post by:
Say I have a class A, and a class B that inherits from A. Now A (and B)
has a virtual destructor and a virtual function F();
If I now make these statements
A* ptrA = new B;
ptrA->F();
delete...
|
by: vaividhya |
last post by:
We can have virtual destructors.Why we can't have virtual constructors?
|
by: Henrik Goldman |
last post by:
Hi
I've had a problem with gcc mac osx which I think I figured out. I would
like to double check with people here to see if my understanding is correct:
I have a class A which class B inherit...
|
by: vabby |
last post by:
Hi
I have run into an eerie situation whihc i cant make out. I have a
class A which has has two virtual functions with the same name, having
diff arguments. Basically a case of function...
|
by: v4vijayakumar |
last post by:
Is it possible to implement member object's virtual functions, in the
containing class? If not, is it possible to simulate this behavior?
ex:
class test
{
protected:
virtual void fun() = 0;...
|
by: Jess |
last post by:
Hello,
If I have a class that has virtual but non-pure declarations, like
class A{
virtual void f();
};
Then is A still an abstract class? Do I have to have "virtual void
f() = 0;"...
|
by: siddhu |
last post by:
Dear experts,
A virtual function has to have an address. So if an inline virtual
function is actually inlined then in that case what does address of
this function signify? How does compiler know...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
| |