can I override private functions?

N

Nick Keighley

I take it this is wrong:-

class Direct_draw
{
public:
Direct_draw ();

virtual ~Direct_draw ()
{}

private:
virtual void draw_primary () = 0;
};

class Dd_animation: public Direct_draw
{
public:
Dd_animation()
{}

~Dd_animation()
{}

private:
virtual void draw_primary ()
{}
};



Direct_draw::Direct_draw ()
{
draw_primary();
}

int main (void)
{
Direct_draw* animation = new Dd_animation();
return 0;
}



it gives a linker error for draw_primary()
 
M

mlimber

I take it this is wrong:-

class Direct_draw
{
public:
Direct_draw ();

virtual ~Direct_draw ()
{}

private:
virtual void draw_primary () = 0;

};

class Dd_animation: public Direct_draw
{
public:
Dd_animation()
{}

~Dd_animation()
{}

private:
virtual void draw_primary ()
{}

};

Direct_draw::Direct_draw ()
{
draw_primary();

}

int main (void)
{
Direct_draw* animation = new Dd_animation();
return 0;

}

it gives a linker error for draw_primary()

You can certainly override private virtual functions; you just can't
call virtuals from the ctor:

http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5

Cheers! --M
 
R

Rolf Magnus

Nick said:
I take it this is wrong:-
Yes.

class Direct_draw
{
public:
Direct_draw ();

virtual ~Direct_draw ()
{}

private:
virtual void draw_primary () = 0;
};
....

Direct_draw::Direct_draw ()
it gives a linker error for draw_primary()

Polymorphism in constructors and destructors works different from what you
seem to expect. In Direct_draw's constructor, the object is a Direct_draw,
since the derived class constructor hasn't yet been called. So regarding
polymorphism, when calling draw_primary() from Direct_draw's constructor,
the draw_primary() from that class is called. However, you don't provide an
implementation, so you get a linker error.
 
R

Rolf Magnus

mlimber said:
You can certainly override private virtual functions; you just can't
call virtuals from the ctor:

http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5

The FAQ claims that dynamic binding isn't happening in constructors and
destructors, but that's actually not true. Dynamic binding does happen, but
only up to the class the constructor/destructor belongs to. Consider the
following example:

#include <iostream>

class Base
{
public:
void test() { virtual_function(); }
virtual void virtual_function() { std::cout << "Base\n"; }
};

class Derived : public Base
{
public:
Derived() { test(); }
virtual void virtual_function() { std::cout << "Derived\n"; }
};

int main()
{
Derived d;
}

Without dynamic binding, this would print "Base", but it does
print "Derived".
 
A

Alf P. Steinbach

* Rolf Magnus:
The FAQ claims that dynamic binding isn't happening in constructors and
destructors

Well no, it doesn't claim that. But it might seem to. My fault, for
insisting on discussing dynamic binding down to the class used to
instantiate the object (the next FAQ item).

There is a shortage of useful terminology, with otherwise suitable words
and terms already having established, unsuitable meanings.

"Dynamic Binding During Initialization" was a compromise (Marshall's
idea, I wanted "virtual construction"), which I think is about the best
that can be done, but as you point out it seems to erronously indicate
that you don't get dynamic binding during initialization by default.
 
M

Markus Svilans

I take it this is wrong:-

class Direct_draw
{
public:
Direct_draw ();

virtual ~Direct_draw ()
{}

private:
virtual void draw_primary () = 0;

};

class Dd_animation: public Direct_draw
{
public:
Dd_animation()
{}

~Dd_animation()
{}

private:
virtual void draw_primary ()
{}

};

Direct_draw::Direct_draw ()
{
draw_primary();

}


When the Direct_draw constructor is called, the object is still a
Direct_draw object, not a Dd_animation object as you might expect.
This is why, during the Direct_draw constructor call, draw_primary()
is still a pure virtual method. Your linker error is probably
something along the lines of "attempt to call pure virtual method"?

One solution to this problem is to have a public initialize() method,
which must be called manually after any Direct_draw-derived object is
created. Any initialization you need to do, including virtual method
calls, can be included in initialize(). The problem with this is that
you might forget to call it, resulting in bugs in your code.

Another solution would be lazy initialization. Here you'd call
initialize() in each method that requires the object to be
initialized. The initialize() method would only run the initialization
code if it has not already been run. The problem with this is that you
will probably have to remember to call initialize() in each of your
derived methods. If you forget, you might run a method on an
uninitialized object, resulting in bugs.

Other people in this group will probably suggest better solutions.

Regards,
Markus.
 
R

Rolf Magnus

Alf said:
* Rolf Magnus:

Well no, it doesn't claim that. But it might seem to.

Some parts (especially question 23.6 and its answer) seem to imply it.
My fault, for insisting on discussing dynamic binding down to the class
used to instantiate the object (the next FAQ item).

There is a shortage of useful terminology, with otherwise suitable words
and terms already having established, unsuitable meanings.

"Dynamic Binding During Initialization" was a compromise (Marshall's
idea, I wanted "virtual construction"), which I think is about the best
that can be done, but as you point out it seems to erronously indicate
that you don't get dynamic binding during initialization by default.

I think both aren't really good, but I don't have an idea for a better term.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top