473,573 Members | 2,836 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

private pure virtual function

Example code in one of my books intrigues me:

class B {
public:
B* Clone() const {
B* p = DoClone();
assert(typeid(* p) == typeid(*this));
return p;
}

protected:
B(const B&);

private:
virtual B* DoClone() const = 0;
};

This will force all derived classes to implement DoClone, or else Clone in
the base class will fail in the assert. Could someone please explain why?

Is typeid of *this for some derived class D of type D or B? I'm sure *p is
of whatever type overrides DoClone, but i'm not sure about *this in the base
class function (even though a derived type is actually in place)... (i may
be getting confused by the whole don't use virtual functions in
constructors, and this pointer advice...)

Also another thing. pure virtual function is private??? What the hell??? Is
it really standard compliant? Can you override it in derived classes
(portably according to the standard) and still keep it private in derived
classes? Does it mean that virtuality of a function applies no matter whta
it's access qualifier is???

Thanks
Nov 1 '05 #1
10 7283
Martin Vorbrodt wrote:
Example code in one of my books intrigues me:

class B {
public:
B* Clone() const {
B* p = DoClone();
assert(typeid(* p) == typeid(*this));
return p;
}

protected:
B(const B&);

private:
virtual B* DoClone() const = 0;
};

This will force all derived classes to implement DoClone, or else Clone in
the base class will fail in the assert. Could someone please explain why?
typeid returns 'type_info' for the most derived class. If 'DoClone' does
not create an instance of the same class as 'this' points to when 'Clone'
is called, then the assertion fails.
Is typeid of *this for some derived class D of type D or B?
D&
I'm sure *p is
of whatever type overrides DoClone, but i'm not sure about *this in the base
class function (even though a derived type is actually in place)... (i may
be getting confused by the whole don't use virtual functions in
constructors, and this pointer advice...)
The assertion is that the most derived classes from both '*this' and '*p'
are the same.
Also another thing. pure virtual function is private??? What the hell??? Is
it really standard compliant?
Why not?
Can you override it in derived classes
(portably according to the standard) and still keep it private in derived
classes? Does it mean that virtuality of a function applies no matter whta
it's access qualifier is???


Virtuality and access specifiers are orthogonal.

V
Nov 1 '05 #2
"Martin Vorbrodt" <mv*******@gmai l.com> wrote in message
news:HM******** **********@news-wrt-01.rdc-nyc.rr.com...
Example code in one of my books intrigues me:

class B {
public:
B* Clone() const {
B* p = DoClone();
assert(typeid(* p) == typeid(*this));
return p;
}

protected:
B(const B&);

private:
virtual B* DoClone() const = 0;
};

This will force all derived classes to implement DoClone, or else Clone in
the base class will fail in the assert. Could someone please explain why?
Clone is receiving a B pointer from DoClone. So DoClone is supposed to make
a clone of itself. Clone then checks to make sure that the clone created is
the same type os the instance of the class it's run on. I.E. If DoClone
simply does return new B* the assert will fail, since DoClone is only run on
derieved classes. If DoClone does return new D* the assert should not fail
(presuming D is the derived from B) since the typeid's will match.
Is typeid of *this for some derived class D of type D or B? I'm sure *p is
of whatever type overrides DoClone, but i'm not sure about *this in the
base class function (even though a derived type is actually in place)...
(i may be getting confused by the whole don't use virtual functions in
constructors, and this pointer advice...)
The this pointer will be a type of the instance of the class, whatever that
is. Since B is a pure virtual class, it would have to be some derieved.
Also another thing. pure virtual function is private??? What the hell???
Is it really standard compliant? Can you override it in derived classes
(portably according to the standard) and still keep it private in derived
classes? Does it mean that virtuality of a function applies no matter whta
it's access qualifier is???


pure virtual can be public or private (not sure about protected). Public or
private really doesn't matter as far as pure virtual is concerned I don't
believe.
Nov 1 '05 #3
Jim Langston wrote:

pure virtual can be public or private (not sure about protected). Public or
private really doesn't matter as far as pure virtual is concerned I don't
believe.


Private pure virtual functions don't make much sense, since they can't
be overridden. Protected pure virtuals do. e.g.:

class Base {
public:
void SomeFunc()
{
DoSomethingVirt ually();
}
protected:
virtual void DoSomethingVirt ually() = 0;
};
Nov 2 '05 #4
"red floyd" <no*****@here.d ude> wrote in message
news:BD******** *********@newss vr11.news.prodi gy.com...
Jim Langston wrote:

pure virtual can be public or private (not sure about protected). Public
or private really doesn't matter as far as pure virtual is concerned I
don't believe.


Private pure virtual functions don't make much sense, since they can't be
overridden. Protected pure virtuals do. e.g.:

class Base {
public:
void SomeFunc()
{
DoSomethingVirt ually();
}
protected:
virtual void DoSomethingVirt ually() = 0;
};


not according to Victor ;)
Nov 2 '05 #5
* red floyd:
Jim Langston wrote:

pure virtual can be public or private (not sure about protected). Public or
private really doesn't matter as far as pure virtual is concerned I don't
believe.


Private pure virtual functions don't make much sense, since they can't
be overridden.


They can be overridden.

Access is orthogonal to virtuality.

I think this is in the FAQ somewhere, check it out.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 2 '05 #6
Alf P. Steinbach wrote:
* red floyd:
Jim Langston wrote:
pure virtual can be public or private (not sure about protected). Public or
private really doesn't matter as far as pure virtual is concerned I don't
believe.


Private pure virtual functions don't make much sense, since they can't
be overridden.

They can be overridden.

Access is orthogonal to virtuality.

I think this is in the FAQ somewhere, check it out.


OK, thanks. However, I submit that it's not a good idea, because you
may get unexpected behavior.
Nov 2 '05 #7
* red floyd:
Alf P. Steinbach wrote:
* red floyd:
Jim Langston wrote:

pure virtual can be public or private (not sure about protected). Public or
private really doesn't matter as far as pure virtual is concerned I don't
believe.

Private pure virtual functions don't make much sense, since they can't
be overridden.

They can be overridden.

Access is orthogonal to virtuality.

I think this is in the FAQ somewhere, check it out.


OK, thanks. However, I submit that it's not a good idea, because you
may get unexpected behavior.


Sometimes. Generally it's opposite, because a pure virtual function in
a class T that has an implementation in class T can be confusing: there
is then the question of what that implementation is meant for, e.g., is
it required to be called by any derived class' implementation?

When a pure virtual function has no implementation in the class it's
declared in, as is the most common, then there is no implementation that
_can_ be made available to derived classes. All that a derived class
can do is to implement it or redeclare it.

Hence it's meaningless to make that pure virtual function protected
(there is nothing callable), and so it's IMO better to make it private;
at least that's not meaningless. More generally, unless a member
function's implementation is meant to be callable by derived classes, it
shouldn't be protected. It should then be private.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 2 '05 #8

Martin Vorbrodt wrote:
Example code in one of my books intrigues me:

class B {
public:
B* Clone() const {
B* p = DoClone();
assert(typeid(* p) == typeid(*this));
return p;
}

protected:
B(const B&);

private:
virtual B* DoClone() const = 0;
};

This will force all derived classes to implement DoClone, or else Clone in
the base class will fail in the assert. Could someone please explain why?
Well, suppose you have some X class you can call Clone() on an instance
of it it, and everything is cool. You get back an X object, because
there is an X::Clone(). Now you make a derived Y from X, but forget to
override Clone(). When you call Clone() on an instance of Y, you are
calling X::Clone(), which only clones the X parts! You get back an X
object that has no Y parts.

This programmer wanted to avoid that mistake. So firstly, he split the
clone function into two. A base class wrapper, and a DoClone() virtual
which cannot be called directly.
Is typeid of *this for some derived class D of type D or B? I'm sure *p is
typeid uses run-time type information; it gets the actual run-time
type.
of whatever type overrides DoClone, but i'm not sure about *this in the base
class function (even though a derived type is actually in place)... (i may
It doesn't matter. Both p and this are just pointers. The p pointer is
a pointer to the newly cloned object, and this is a pointer to the
object that was cloned. The assertion is simply that they both have the
same type. I.e. the bug of forgetting to override DoClone() has not
occured.
Also another thing. pure virtual function is private??? What the hell??? Is
That's so people could not call DoClone() directly, which would bypass
the safety check.

In a language with auxiliary methods, like Common Lisp, you would just
use an :around method. C++ doesn't have those, so if you want to wrap
additional advice methods around a method call, you split things up
into multiple functions, such as a base class wrapper that calls
virtual "helpers".

Here is how I would do exactly the same thing in that language:

(defmethod clone :around ((obj t))
(let ((new-obj (call-next-method)))
(assert (eq (class-of new-obj) (class-of obj))
new-obj))

The :around keyword specifies that this is an "around" auxiliary
method, and (obj t) means we have one argument called obj, which is of
class T. T is the superclass of all classes. I.e. this method is at the
root of the class hierarchy. Whenever the primary CLONE method is
called, this thing gets control first.

We call the primary CLONE method using (call-next-method), which is a
special function in the object system that an around method to pass
control down the chain. If we don't invoke this, the primary CLONE will
never be called, and around methods can choose to do that.

We catch the cloned object, bind it to the local variable NEW-OBJ, and
then assert that it has exactly the same class as OBJ.

We can now write a couple of primary methods to test. How about one
specialized for integers:

(defmethod clone ((obj integer))
obj)

we "clone" an integer just by returning it. Integers are immutable
objects, so we can return the same object and say we have cloned it.
This works just fine:

(clone 42) --> 42

Now let's write a broken CLONE, which takes a string:

(defmethod clone ((obj string))
(list 1 2)) ;; wrong!

It returns a list instead of cloning the string:

(clone "abc") --> *assertion!*

Boom, the assertion goes off, signaling a condition. Under CLISP the
assertion condition has this text:

"(EQ (CLASS-OF NEW-OBJ) (CLASS-OF OBJ)) must evaluate to a non-NIL
value."

There is no way for the programmer to call the primary CLONE method
directly; it's under the control of the method combination system.

That part is simulated in C++ by renaming the primary function to
DoClone, and then documenting that as being an internal interface, and
please would everyone go through Clone.

So when I saw this C++ class, I right away identified it as a clumsy
around method type of thingy. :)
it really standard compliant? Can you override it in derived classes
(portably according to the standard) and still keep it private in derived
classes? Does it mean that virtuality of a function applies no matter whta
it's access qualifier is???


Access specifiers don't control visibility, only access. You can
inherit a private virtual function, and override it with a public one.
The two are identified as the same function based on their name and
type signature.

Access specifiers only control which call sites are permitted to access
the member.

The real protection in this example comes not from the private:
specifier, but from the renaming of Clone to DoClone().

Someone can derive this class, and implement DoClone() as a public
function, allowing anyone to call it. They are then calling the
improper interface, because they should be going through Clone().

Nov 2 '05 #9

red floyd wrote:
Alf P. Steinbach wrote:
* red floyd:
Jim Langston wrote:

pure virtual can be public or private (not sure about protected). Public or
private really doesn't matter as far as pure virtual is concerned I don't
believe.

Private pure virtual functions don't make much sense, since they can't
be overridden.

They can be overridden.

Access is orthogonal to virtuality.

I think this is in the FAQ somewhere, check it out.


OK, thanks. However, I submit that it's not a good idea, because you
may get unexpected behavior.


Fiddling with access specifiers has no effect on run-time behavior.
Adding an access specifier can turn a program that requires no
diagnostics into a program that requires a diagnostic.

Nov 2 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
4341
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining it inline. Like this.
6
3458
by: pakis | last post by:
I am having a problem of pure virtual function call in my project. Can anyone explaine me the causes of pure virtual function calls other than calling a virtual function in base class? Thanks
3
2331
by: sudhir | last post by:
I defined a pure virtual function like virtual void sum()=0; <--- pure virtual function but If I defined a virtual function in a base class in case of multilevel inheritance for the base pointer to point the right function with same signature in base and derived class like-- virtual void sum() { }
21
2548
by: sks | last post by:
Hi , could anyone explain me why definition to a pure virtual function is allowed ?
10
4780
by: John Goche | last post by:
Hello, page 202 of Symbian OS Explained by Jo Stichbury states "All virtual functions, public, protected or private, should be exported" then page 203 states "In the rare cases where a pure virtual function body
14
4177
by: v4vijayakumar | last post by:
Why we need "virtual private member functions"? Why it is not an (compile time) error?
7
24534
by: sam_cit | last post by:
Hi Everyone, I wanted to know as to what is the exact difference between a virtual function and a pure virtual function? Thanks in advance!!!
10
2080
by: Rahul | last post by:
Hi, I tried to create a abstract class by having a non-virtual member function as pure, but i got a compilation error saying "only virtual member functions can be pure"... I'm trying to think the reason behind this restriction... i just want to want a base class to be abstract so as to avoid object slicing into the base type from derived...
14
2734
by: Jack | last post by:
Hi, I meet a question with it , I did not get clear the different betteen them, for example: #include <iostream>
0
7760
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7679
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7996
Oralloy
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8191
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
8049
tracyyun
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6392
agi2029
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5573
isladogs
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3724
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
1029
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.