Click to See Complete Forum and Search --> : Is a non-virtual member function without an implementation legal ?
Yves M
September 5th, 2002, 11:26 AM
I noticed something strange in VC 6. Take the following code :
class CTest {
public:
CTest()
{
}
void CalledFunc();
void NotCalledFunc();
};
void CTest::CalledFunc()
{
}
int main()
{
CTest *ptst = new CTest;
ptst->CalledFunc();
delete ptst;
return 0;
}
This compiles and runs correctly, even though I've never provided an implementation of NotCalledFunc. Should it not give me at least an unresolved external error during compilation, or is this behaviour specified like this in the C++ standard ?
The reason why this happens in VC seems obvious. The compiler automatically strips away functions which are never called, so that the implementation of NotCalledFunc is never actually needed.
cup
September 5th, 2002, 01:30 PM
Does the same on Sun, HPUX, Watcom, Borland and Code Warrior compilers but I don't know whether it is legal or not.
Yves M
September 5th, 2002, 01:42 PM
Interesting... Well, it might be legal then...
There is of course not much point in doing this, but it would be nice if the compiler could warn me that I haven't implemented functions which I've declared :/
Graham
September 5th, 2002, 03:34 PM
Absolutely fine. No problem. Totally legal.
It's the simplest way of denying copy semantics to a class:
class foo
{
public:
// whatever
private:
foo(const foo&); // No definition
void operator=(const foo&); // No definition
};
There's no need to define the copy ctor or the copy assign, since they can't be called from outside the class, and you're not going to call them from inside the class (are you?).
The linker will warn you if you try to use an undefined (accessible) function.
Yves M
September 5th, 2002, 05:51 PM
Interesting :)
cup
September 6th, 2002, 12:49 AM
We use the "denying copy semantics" a lot. And yes, I've just looked - there is no code for it.
Graham
September 6th, 2002, 06:06 AM
As a sort of opposite to that, Yves, were you aware that you are allowed to provide a body for a pure virtual function?
class foo
{
public:
virtual ~foo(){}
virtual void f() = 0;
};
void foo::f()
{
// Do something
}
class bar : public foo
{
public:
void f() { foo::f(); }
};
So what's the point of that?
Consider if foo::f() had not been declared pure (all else unchanged). What we are saying when we provide a body for a virtual function in a base class is "here is a default implementation". Consider if a derived class does not provide an override for that virtual function - the derived class will display the default behaviour (from the base class). Now, what if not providing the override was a mistake? How long before that mistake is discovered? No compilation error, no link error, probably no run-time error, just peculiar behaviour.
In the example I gave above, the designer of foo is saying:
"Here is a default implementation of function f(). If you wish to use that default, you must make a conscious decision to do so."
Note that, if you forget to override f in bar, then bar becomes an abstract class (because foo is abstract), so any attempt to create a bar object will throw a compilation error. Much easier to track down.
jfaust
September 6th, 2002, 08:56 AM
Now that I didn't know. Neat.
Jeff
Yves M
September 6th, 2002, 10:38 AM
Interesting point, Graham, I didn't know that one either :)
I have to say that class structures in C++ are much more expressive than in Java. It is probably a good thing. I guess that's part of why C++ takes so much longer to learn ;)
Dallex
September 6th, 2002, 11:38 AM
Of course it's legal. I usually declare my functions in a class well before I get around to defining them. I'd hate to have to write stubs before I could compile and run, to checkout a few functions in the begining.
John E
September 7th, 2002, 12:48 PM
Here's something else that's little known. In fact I was programming for years before I realised this....
What exactly is a virtual function? For years I always thought you had to declare a function as virtual in order to override it in a derived class. In fact I'm certain I've read that in lots of text books. Not so in fact. A function in a base class can be overridden in a derived class regardless of whether it is virtual or not. However, if it isn't declared as virtual and some function in the base class calls it, the base class function will be called by the base class and the derived function will be called by the derived class. What 'virtual' does is to allow a base class to 'know about' (and therefore call) equivalent functions in a derived class. Neat eh?
We live and learn (well I certainly do!)
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.