473,394 Members | 1,869 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Implementation of abstract classes

Hi folks.

I have some classes which are derived from some base:

class base {
void foo();
void bar();
};

class a : public base {
};

class b: public base{
};

The problem is as follows:

1) I would like to prevent users from making instances of
class base
2) There are no overloaded functions beween the base class
and the derived classes, so I can not use the usual

virtual void overloaded_function() = 0;

in the base class.

As far as I can see, there are two ways to proceed:

1) make some virtual dummy function that the
derived classes need to implement
2) Hide the constructor of base as protected.

From a semantic point of view the latter solution
seems the more elegant. Is this a good solution
or are there traps or snags associated with it?

Rune
Sep 20 '08 #1
11 1213
Rune Allnor wrote:
1) I would like to prevent users from making instances of
class base
2) There are no overloaded functions beween the base class
and the derived classes, so I can not use the usual

virtual void overloaded_function() = 0;

in the base class.
If your base class is going to be used polymorphically, you must declare
its destructor virtual anyway, so you don't need a "dummy" pure virtual
function. Just declare the destructor itself pure virtual:

virtual ~base() = 0
--
Christian Hackl
Sep 20 '08 #2
Rune Allnor wrote:
1) I would like to prevent users from making instances of
class base
2) There are no overloaded functions beween the base class
and the derived classes, so I can not use the usual

virtual void overloaded_function() = 0;

in the base class.

As far as I can see, there are two ways to proceed:

1) make some virtual dummy function that the
derived classes need to implement
2) Hide the constructor of base as protected.
If your base class is going to be used polymorphically, you must declare
its destructor virtual anyway, so you don't need a "dummy" pure virtual
function. Just declare the destructor itself pure virtual:

virtual ~base() = 0
--
Christian Hackl
Sep 20 '08 #3
On 20 Sep, 18:40, Christian Hackl <ha...@sbox.tugraz.atwrote:
Rune Allnor wrote:
1) I would like to prevent users from making instances of
* *class base
2) There are no overloaded functions beween the base class
* *and the derived classes, so I can not use the usual
* *virtual void overloaded_function() = 0;
* *in the base class.
As far as I can see, there are two ways to proceed:
1) make some virtual dummy function that the
* *derived classes need to implement
2) Hide the constructor of base as protected.

If your base class is going to be used polymorphically, you must declare
its destructor virtual anyway, so you don't need a "dummy" pure virtual
function. Just declare the destructor itself pure virtual:

virtual ~base() = 0
Of course!

This solution takes care of the case I'm working on
right now, but how would one do this if there were
some cleaning up to do on the base class level?

With the above solution one would have to call some
base::cleanup() function in each of the derived
destructors, right?

Rune
Sep 20 '08 #4
On 2008-09-20 18:52, Rune Allnor wrote:
On 20 Sep, 18:40, Christian Hackl <ha...@sbox.tugraz.atwrote:
>Rune Allnor wrote:
1) I would like to prevent users from making instances of
class base
2) There are no overloaded functions beween the base class
and the derived classes, so I can not use the usual
virtual void overloaded_function() = 0;
in the base class.
As far as I can see, there are two ways to proceed:
1) make some virtual dummy function that the
derived classes need to implement
2) Hide the constructor of base as protected.

If your base class is going to be used polymorphically, you must declare
its destructor virtual anyway, so you don't need a "dummy" pure virtual
function. Just declare the destructor itself pure virtual:

virtual ~base() = 0

Of course!

This solution takes care of the case I'm working on
right now, but how would one do this if there were
some cleaning up to do on the base class level?

With the above solution one would have to call some
base::cleanup() function in each of the derived
destructors, right?
Just because a function is pure virtual does not mean it cannot be
implemented:

#include <iostream>

struct Base
{
virtual ~Base() = 0
{
std::cout << "~Base\n";
}
};

struct Derived : public Base
{
~Derived()
{
std::cout << "~D\n";
}
};

int main() {
Derived d;
return 0;
}

--
Erik Wikström
Sep 20 '08 #5
On Sep 20, 8:12*pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2008-09-20 18:52, Rune Allnor wrote:


On 20 Sep, 18:40, Christian Hackl <ha...@sbox.tugraz.atwrote:
Rune Allnor wrote:
1) I would like to prevent users from making instances of
* *class base
2) There are no overloaded functions beween the base class
* *and the derived classes, so I can not use the usual
* *virtual void overloaded_function() = 0;
* *in the base class.
As far as I can see, there are two ways to proceed:
1) make some virtual dummy function that the
* *derived classes need to implement
2) Hide the constructor of base as protected.
If your base class is going to be used polymorphically, you must declare
its destructor virtual anyway, so you don't need a "dummy" pure virtual
function. Just declare the destructor itself pure virtual:
virtual ~base() = 0
Of course!
This solution takes care of the case I'm working on
right now, but how would one do this if there were
some cleaning up to do on the base class level?
With the above solution one would have to call some
base::cleanup() function in each of the derived
destructors, right?

Just because a function is pure virtual does not mean it cannot be
implemented:

#include <iostream>

struct Base
{
* virtual ~Base() = 0
* {
* * std::cout << "~Base\n";
* }
verrry interesting!!!!!!!!!!!!!!!!!!!
are you sure???????????????????????

regards,
FM.
Sep 20 '08 #6
On Sep 20, 6:07 pm, Rune Allnor <all...@tele.ntnu.nowrote:
I have some classes which are derived from some base:
class base {
void foo();
void bar();
};
class a : public base {
};
class b: public base{
};
The problem is as follows:
1) I would like to prevent users from making instances of
class base
2) There are no overloaded functions beween the base class
and the derived classes, so I can not use the usual
virtual void overloaded_function() = 0;
in the base class.
As far as I can see, there are two ways to proceed:
1) make some virtual dummy function that the
derived classes need to implement
2) Hide the constructor of base as protected.
From a semantic point of view the latter solution
seems the more elegant. Is this a good solution
or are there traps or snags associated with it?
I don't know about elegance, but the second solution is
certainly the usual solution.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 20 '08 #7
On 20 Sep, 19:12, Erik Wikström <Erik-wikst...@telia.comwrote:
Just because a function is pure virtual does not mean it cannot be
implemented:

#include <iostream>

struct Base
{
* virtual ~Base() = 0
* {
* * std::cout << "~Base\n";
* }
};
Can this be correct? The way I understand

virtual void foo() = 0;

is that the statement inituializes a NULL
pointer in the virtaul function table.
It this is correct your code above will
result in undefined behaviour.

Rune
Sep 21 '08 #8
On 2008-09-21 16:55, Rune Allnor wrote:
On 20 Sep, 19:12, Erik Wikström <Erik-wikst...@telia.comwrote:
>Just because a function is pure virtual does not mean it cannot be
implemented:

#include <iostream>

struct Base
{
virtual ~Base() = 0
{
std::cout << "~Base\n";
}
};

Can this be correct? The way I understand

virtual void foo() = 0;

is that the statement inituializes a NULL
pointer in the virtaul function table.
It this is correct your code above will
result in undefined behaviour.
Actually it is *not* a correct solution to Rune's problem, but not
because the reason you mentioned. The C++ standard does not mention
vtables or such things, it only defines what is supposed to happen and
leaves to the compiler to use the best technique to make it happen.

The "= 0" at the end of a function declaration means that the function
is pure virtual, and a class with a pure virtual function is abstract
(it can not be instantiated). This means that any derived classes have
to either implement the function or they will abstract too.

The reasons my code was not correct is that the standard does not allow
a pure function to be defined together with the declaration:

struct Foo
{
virtual void bar() = 0 { 1+1; } // Error
};

You can, however, provide the the definition separately:

struct Foo
{
virtual void bar() = 0;
};

void Foo::bar()
{
1 + 1;
}

You can also call a pure virtual function using a qualified expression:

struct Foo
{
virtual void bar() = 0;
};

void Foo::bar()
{
std::cout << "Foo::bar()\n";
}

struct Baz : public Foo
{
void bar()
{
std::cout << "Baz::bar()\n"
Foo::bar();
}
};

int main()
{
Foo* f = new Baz();
f->bar();
return 0;
}

Output:
Baz::bar()
Foo::bar()

--
Erik Wikström
Sep 21 '08 #9
On Sep 21, 4:55 pm, Rune Allnor <all...@tele.ntnu.nowrote:
On 20 Sep, 19:12, Erik Wikström <Erik-wikst...@telia.comwrote:
Just because a function is pure virtual does not mean it
cannot be implemented:
#include <iostream>
struct Base
{
virtual ~Base() = 0
{
std::cout << "~Base\n";
}
};
Can this be correct? The way I understand
virtual void foo() = 0;
is that the statement inituializes a NULL pointer in the
virtaul function table.
It might. All the standard says is that if a virtual function
call resolves to a pure virtual function, the behavior is
undefined.
It this is correct your code above will result in undefined
behaviour.
Only if you manage to have a virtual function call resolve to
Base::~Base. And I don't see any way of doing that that
wouldn't create undefined behavior anyway. (Basically, the only
way you could have it would be with an explicit destructor call
from a constructor or the destructor of Base.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 21 '08 #10
Rune Allnor wrote:
Can this be correct? The way I understand

virtual void foo() = 0;

is that the statement inituializes a NULL
pointer in the virtaul function table.
You understand wrongly. The "=0" part is nothing more than a way of
saying "pure". (The story goes that Stroustrup wanted to use the keyword
"pure", but the standardization committee didn't want any more
single-use keywords, so Stroustrup came up with the next best thing he
could come up with, which was adding "=0" to the method declaration.)

A pure virtual function is in all ways a regular virtual function,
with the exception that it *must* be implemented in a derived class, and
if there's a pure virtual function in the base class, that base class
cannot be instantiated all by itself. The difference between a virtual
function and a pure virtual function is purely semantical.

This means that a pure virtual function can have an implementation in
the exact same way as a regular virtual function can. You can call this
implementation by calling it explicitly, eg. Base::foo();

In the case of a pure virtual destructor, the destructor of the base
class is called automatically (so it doesn't need to be called explicitly).
Sep 21 '08 #11
On Sep 22, 12:29 am, Juha Nieminen <nos...@thanks.invalidwrote:

[...]
(The story goes that Stroustrup wanted to use the keyword
"pure", but the standardization committee didn't want any more
single-use keywords, so Stroustrup came up with the next best
thing he could come up with, which was adding "=0" to the
method declaration.)
I too have heard that there was a desire not to introduce new
keywords at that time, but you can't blame the committee: pure
virtual functions were present before the committee was founded.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 22 '08 #12

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

Similar topics

9
by: Anon Email | last post by:
Hi people, I'm learning about header files in C++. The following is code from Bartosz Milewski: // Code const int maxStack = 16; class IStack
4
by: WittyGuy | last post by:
Hi all, Though I know the concepts of both abstract class & virtual function (like derived class pointer pointing to base class...then calling the function with the pointer...), what is the real...
12
by: Daedalus.OS | last post by:
Ok first I'm pretty new to OOP, so my question may sound stupid to some of you. If the only answer you can provide is "get a book about OOP" then don't loose your time and mine cause it's already...
5
by: Keith Patrick | last post by:
Could someone tell me if it's possible (and if so, how) to call an explicitly-implemented interface method from a subclass? I have a class in which I have to explicity implement some methods, but...
6
by: Zach | last post by:
Hi everyone, I'm a bit of a newbie to C# programming so forgive this innocent question, but coming from a C++ background this seems very odd to me, and I'm hoping someone can shed some light...
7
by: tron.thomas | last post by:
Please consider the following code: class Abstract { public: virtual ~Abstract() {} virtual void Method() = 0; }; class Concrete : public virtual Abstract
3
by: John Glover | last post by:
To whoever can help, I've been having a problem with XML deserialization lately. I needed to serialize and deserialze two objects which inherited from Hashtable. Because IDictionary...
2
by: Ben Voigt | last post by:
The C# Language Specification says: A virtual property declaration specifies that the accessors of the property are virtual. The virtual modifier applies to both accessors of a read-write...
18
by: bsruth | last post by:
I tried for an hour to find some reference to concrete information on why this particular inheritance implementation is a bad idea, but couldn't. So I'm sorry if this has been answered before....
20
by: Luc Kumps | last post by:
(Sorry about the previous post, it got transmitted before it was complete) We try to separate implementation and interface defintions, but we run into a problem. I hope the guru's can solve this,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
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...
0
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...
0
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,...
0
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...
0
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...

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.