473,407 Members | 2,629 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,407 software developers and data experts.

Base struct instead of class

Taken out of C++ In a Nutshell book...

Example 7-18: Using an abstract classes as interface specification.
struct Runnable {
virtual void run() = 0;
};

struct Hashable {
virtual size_t hash() = 0;
};

class Thread : public Runnable, public Hashable {
public:
Thread() { start_thread(*this); }
Thread(const Runnable& thread) { start_thread(thread); }
virtual void run();
virtual size_t hash() const { return thread_id(); }
size_t thread_id() const;
...
private:
static void start_thread(const Runnable&);
};

What would the advantage be of using struct as an interface (pure virtual
base class)?
Thanks,Martin
Jul 19 '05 #1
22 5798
brevity. Thus you don't have to type:

class Runnable
{
public:
virtual void run() = 0;
};

Otherwise there is no advantage. Personally I use struct only when I want
to group variables so that I might write it as a block of bytes to a file or
read from a file. Otherwise I use class if the intention is to contain
functionality (e.g. methods).

Tom

"Marcin Vorbrodt" <mv*****@eos.ncsu.edu> wrote in message
news:bj**********@uni00nw.unity.ncsu.edu...
Taken out of C++ In a Nutshell book...

Example 7-18: Using an abstract classes as interface specification.
struct Runnable {
virtual void run() = 0;
};

struct Hashable {
virtual size_t hash() = 0;
};

class Thread : public Runnable, public Hashable {
public:
Thread() { start_thread(*this); }
Thread(const Runnable& thread) { start_thread(thread); }
virtual void run();
virtual size_t hash() const { return thread_id(); }
size_t thread_id() const;
...
private:
static void start_thread(const Runnable&);
};

What would the advantage be of using struct as an interface (pure virtual
base class)?
Thanks,Martin

Jul 19 '05 #2
Thomas J. Clancy wrote:
brevity. Thus you don't have to type:

<snip>

Please don't top-post. Re-read section 5 of the FAQ for posting
guidelines. You could also find this rule in pretty much any netiquette
reference, including RFC 1855.

http://www.parashift.com/c++-faq-lite/

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jul 19 '05 #3

"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:h6***************@newsread4.news.pas.earthlin k.net...
Thomas J. Clancy wrote:
brevity. Thus you don't have to type:

<snip>

Please don't top-post. Re-read section 5 of the FAQ for posting
guidelines. You could also find this rule in pretty much any netiquette
reference, including RFC 1855.

http://www.parashift.com/c++-faq-lite/

-Kevin


Ah yes, I'd forgotten about this particular quirk of posting in most
newsgroups. I find non-top posting appalling unless I am addressing
specific pieces of the posted question or questions. But alas, I am in the
minority. Still, I find it logical that should someone ask one simple
question, rather than have to scan down to find the answer, if it is at the
top he/she can immediately see the answer--thus instant gratification.

Anyway, since it seems to anger you and perhaps others I will, to my own
dismay, comply.

T. Clancy

Jul 19 '05 #4
On Sun, 7 Sep 2003 01:32:18 -0400, "Thomas J. Clancy" <tj******@comcast.net> wrote:

"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:h6***************@newsread4.news.pas.earthli nk.net...
Thomas J. Clancy wrote:
> brevity. Thus you don't have to type: <snip>

Please don't top-post. Re-read section 5 of the FAQ for posting
guidelines. You could also find this rule in pretty much any netiquette
reference, including RFC 1855.

http://www.parashift.com/c++-faq-lite/

-Kevin


Ah yes, I'd forgotten about this particular quirk of posting in most
newsgroups. I find non-top posting appalling unless I am addressing
specific pieces of the posted question or questions. But alas, I am in the
minority. Still, I find it logical that should someone ask one simple
question, rather than have to scan down to find the answer, if it is at the
top he/she can immediately see the answer--thus instant gratification.


That assumes (1) someone has followed the whole thread down to the answer
(which is much work), and (2) a tool that displays the text positioned at
the top by default, and (3) something more complicated than Ctrl-End or
Page Down to move down in the text; I doubt whether all that can be true
very often.

Anyway, since it seems to anger you and perhaps others I will, to my own
dismay, comply.


Thanks, and please pass the word (it's September again).

Jul 19 '05 #5
"Marcin Vorbrodt" <mv*****@eos.ncsu.edu> wrote in message
news:bj**********@uni00nw.unity.ncsu.edu...
Taken out of C++ In a Nutshell book...

Example 7-18: Using an abstract classes as interface specification.
struct Runnable {
virtual void run() = 0;
};

struct Hashable {
virtual size_t hash() = 0;
};


As Thomas mentioned, this only saves you from having to add
a 'public:' specification. Except for the public access
specifications, all uses of keyword 'struct' can be relaced
by 'class' in C++.
Using struct is a matter of style choice. struct is commonly
used for structs that have no methods or invariants, and
have only public data members.
The author of your book chose to apply it to interfaces too.

One comment though: IMO interface classes such as the ones
above should have a protected destructor (if not a virtual
destructor):
class Runnable {
public:
virtual void run() = 0;
protected:
~Runnable() {}
};
If you don't intend users of the interface to delete
instances by using a pointer to this interface, it should
be made explicit -- a protected destructor does it.
If it is acceptable to do so, the destructor shall
be virtual.

See also: http://www.gotw.ca/publications/mill18.htm
"Guideline #4: A base class destructor should be either public and virtual,
or protected and nonvirtual."
I hope you'll find this useful...
--
http://www.post1.com/~ivec <> Ivan Vecerina

Jul 19 '05 #6
Marcin Vorbrodt wrote:
Taken out of C++ In a Nutshell book...

Example 7-18: Using an abstract classes as interface specification.
struct Runnable {
virtual void run() = 0;
};

struct Hashable {
virtual size_t hash() = 0;
};

class Thread : public Runnable, public Hashable {
public:
Thread() { start_thread(*this); }
Thread(const Runnable& thread) { start_thread(thread); }
virtual void run();
virtual size_t hash() const { return thread_id(); }
size_t thread_id() const;
...
private:
static void start_thread(const Runnable&);
};

What would the advantage be of using struct as an interface (pure
virtual base class)?

First: *all* of your classes *must* have a virtual destructor. They all
have virtual functions. Especially hashable and runnable *must* have
virtual destructors.

Second: the advantage is less typing. You do not need to say "public:"

--
WW aka Attila
Jul 19 '05 #7
Thomas J. Clancy wrote:

Ah yes, I'd forgotten about this particular quirk of posting in most
newsgroups.
It applies to all one-to-many communications on the net, not just
newsgroups. See RFC 1855. It's also not a "quirk", it is a standard.
I find non-top posting appalling unless I am addressing
specific pieces of the posted question or questions. But alas, I am in the
minority. Still, I find it logical that should someone ask one simple
question, rather than have to scan down to find the answer, if it is at the
top he/she can immediately see the answer--thus instant gratification.


But then everyone else has to scan down to see what the question was. Is
your time more valuable than that of the hundreds of others reading the
group?

Top-posting creates an illogical ordering of messages and encourages
laziness and over-quoting. Those are the main reasons it is discouraged.
Compare this message to one in a thread with top-posting. This message
is organized, easy to follow, and requires little or no scrolling. The
top-posted message is likely followed by a dozen message going backward
in time, wrapping in inconvenient places do to excessive quote marks,
and taking up hundreds of lines for no good reason. It's nearly
impossible to determine who said what, and the order of the messages is
illogical.

Proper posting has huge advantages over top-posting. That's why we
insist on it, and you should too.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jul 19 '05 #8
White Wolf wrote:

First: *all* of your classes *must* have a virtual destructor. They all
have virtual functions. Especially hashable and runnable *must* have
virtual destructors.


Or protected destructors, as Ivan pointed out.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jul 19 '05 #9

"White Wolf" <wo***@freemail.hu> wrote in message
news:bj**********@phys-news1.kolumbus.fi...
Marcin Vorbrodt wrote:
Taken out of C++ In a Nutshell book...

Example 7-18: Using an abstract classes as interface specification.
struct Runnable {
virtual void run() = 0;
};

struct Hashable {
virtual size_t hash() = 0;
};

class Thread : public Runnable, public Hashable {
public:
Thread() { start_thread(*this); }
Thread(const Runnable& thread) { start_thread(thread); }
virtual void run();
virtual size_t hash() const { return thread_id(); }
size_t thread_id() const;
...
private:
static void start_thread(const Runnable&);
};

What would the advantage be of using struct as an interface (pure
virtual base class)?

First: *all* of your classes *must* have a virtual destructor. They all
have virtual functions. Especially hashable and runnable *must* have
virtual destructors.

Second: the advantage is less typing. You do not need to say "public:"

So it is just as i expected. You still need virtual destructors, so that
base pointers to derived objects get deleted properly right? Even if there
are no actual data fields in the base struct?


--
WW aka Attila


Thanks,
Martin
Jul 19 '05 #10
Kevin Goodsell wrote:
White Wolf wrote:

First: *all* of your classes *must* have a virtual destructor. They
all have virtual functions. Especially hashable and runnable *must*
have virtual destructors.


Or protected destructors, as Ivan pointed out.


As far as I see, not in this case. In general: yes.

--
WW aka Attila
Jul 19 '05 #11
Marcin Vorbrodt wrote:
[SNIP]
So it is just as i expected. You still need virtual destructors, so
that base pointers to derived objects get deleted properly right?
Even if there are no actual data fields in the base struct?


Especially then. If there is no data in the base (pure interface class),
then it is even more important. Why? Because if you do not have any
members in the made, then (when deleting an object via a base pointer) *no*
members will be destructed. And it is very veyr likely that your
implementation classes *will* have members.

--
WW aka Attila
Jul 19 '05 #12
Tim

"White Wolf" <wo***@freemail.hu> wrote in message
news:bj**********@phys-news1.kolumbus.fi...
Marcin Vorbrodt wrote:
[SNIP]
So it is just as i expected. You still need virtual destructors, so
that base pointers to derived objects get deleted properly right?
Even if there are no actual data fields in the base struct?
Especially then. If there is no data in the base (pure interface class),
then it is even more important. Why? Because if you do not have any
members in the made, then (when deleting an object via a base pointer)

*no* members will be destructed. And it is very veyr likely that your
implementation classes *will* have members.


....but isn't Marcin trying to find out if it's safe to NOT have a destructor
in his interface that he passes to clients? For a client to do a delete on
the interface and not have the concrete class's data destroyed is a positive
advantage is it not; the concrete class that hands out these interface needs
to be in control of its data's life-time through refrence counting or some
other means.

Isn't this like a light version of COM? A server hands out abstract
interfaces to clients; the client should not be able to delete the concrete
class by deleting the interface. In this particular case, the interface NOT
having a virtual destructor is just what you want; a delete on it will do
absolutely nothing since it has no allocated memory... assuming that the
concrete class wasn't 'new'd.
Jul 19 '05 #13

"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:GC***************@newsread4.news.pas.earthlin k.net...
Thomas J. Clancy wrote:

Ah yes, I'd forgotten about this particular quirk of posting in most
newsgroups.


It applies to all one-to-many communications on the net, not just
newsgroups. See RFC 1855. It's also not a "quirk", it is a standard.


I know its a standard, but still I maintain that it is quirky. :-)
However, although I could come up with any number of counter arguments,
including examples, of why top-posting could be prefereable to "proper
posting," I would rather just move on and obey the standard and just enjoy
these newsgroups. Besides, my view of the entire issue might be completely
distorted and perhaps proper posting is the better way afterall. Still,
despite the fact that I disagree with the standard doesn't mean that I
cannot follow it, correct? :-)

<soapbox>
To summarize: If we were to follow blindly and consistently all standards,
rules, laws, etc., there would be no innovation nor outlet for creative
thinking and reasoning, and eventually we'd find ourselves bound to a
totalitarian system that would, should we deviate event slightly from its
narrow, yet clearly marked paths, see to it that we are severely punished.
</soapbox>
Jul 19 '05 #14
"Tim" <ti******@hotmail.com> writes:
"White Wolf" <wo***@freemail.hu> wrote in message
news:bj**********@phys-news1.kolumbus.fi...
Marcin Vorbrodt wrote:
[SNIP]
> So it is just as i expected. You still need virtual destructors, so
> that base pointers to derived objects get deleted properly right?
> Even if there are no actual data fields in the base struct?
Especially then. If there is no data in the base (pure interface class),
then it is even more important. Why? Because if you do not have any
members in the made, then (when deleting an object via a base pointer)

*no*
members will be destructed.


Nowhere is this guaranteed. If you have:

struct interface
{
virtual void foo()= 0;
};

struct imp : interface {vector<int> a;};

int main()
{
interface* p= new imp;
delete p;
}

you have _undefined_ behavior. The implementation may destruct a. It
may corrupt the heap. It may throw an exception. It may abort,
etc. Others may tell you the implementation may email your boss,
or cause a demon to emerge from your left nostril, but I will
constrain my list to things I have actually observed with real
implementations. :-)
And it is very veyr likely that your
implementation classes *will* have members.
...but isn't Marcin trying to find out if it's safe to NOT have a destructor
in his interface that he passes to clients?


The only way to not have a destructor in one's interface is to declare
it private or protected. If no destructor is declared, one will be
generated. If the destructor is declared private or protected, the
destructor can only be used in certain places, reducting the
chance that someone will mistakenly call delete where the
pointer's type is inconsistent with the object's dynamic type. If
the destructor is also not defined, any use of delete will result
in a link error. IOWs, my above example is dangerous in part
because it *does* have a destructor. Had I written:

struct interface
{
virtual void foo()= 0;
private:
~interface();
};

//No definition of interface::~interface() ...
//Rest same as before ..

linking the code would result in an error, if delete was used on
an interface*. Since the error prevents misuse of delete, this is
in some sense 'safe', though some other way to release memory
blocks (e.g., a garbage collector) is likely needed.
For a client to do a delete on
the interface and not have the concrete class's data destroyed is a positive
advantage is it not;

[snip]

If that were guaranteed, I am sure someone could find a use for
it. However, it is not guaranteed.
Jul 19 '05 #15

"White Wolf" <wo***@freemail.hu> wrote in message news:bj**********@phys-news1.kolumbus.fi...
First: *all* of your classes *must* have a virtual destructor. They all
have virtual functions. Especially hashable and runnable *must* have
virtual destructors.


Not necessarily true. Do not confuse "rules of thumb" with the MUST rules
of the language. The only time you need a virtual destructor is when derived
classes are deleted through pointers of their base types.
Jul 19 '05 #16
Alf P. Steinbach wrote:

Thanks, and please pass the word (it's September again).


Isn't it always? ;-)

--
Mike Smith

Jul 19 '05 #17
Ivan Vecerina wrote:

As Thomas mentioned, this only saves you from having to add
a 'public:' specification. Except for the public access
specifications, all uses of keyword 'struct' can be relaced
by 'class' in C++.


Or vice versa - one could argue that the "class" keyword was never
necessary at all, whereas "struct", of course, was already pre-existing
in C.

--
Mike Smith
Jul 19 '05 #18
As Thomas mentioned, this only saves you from having to add
a 'public:' specification. Except for the public access
specifications, all uses of keyword 'struct' can be relaced
by 'class' in C++.


Actually, there is one other thing to look out for...

When inheriting, if you don't specify public, inherited or private, the
default will be different depending on whether you inherit from a struct or
class. When inheriting from a struct, it will be public inheritance; when
inheriting from a class, it will be private inheritance.

So, if you replaced all "struct"s with "class"es and added "public" access
specifications as necessary to make all access rights equivalent to what
they were before, it is still possible for the meaning of a program to
change. Specifically, some public inheritance might change to private
inheritance, as stated above...

Jul 19 '05 #19

"Mike Smith" <mi*******************@acm.DOT.org> wrote in message
news:vl************@news.supernews.com...

Or vice versa - one could argue that the "class" keyword was never
necessary at all, whereas "struct", of course, was already pre-existing
in C.


Or, since the meaning of struct has changed from C, one could argue that
struct shouldn't do anything different from what it did in C, but only the
new keyword class should be used to implement classes.
Jul 19 '05 #20
Dave Theese wrote:

When inheriting, if you don't specify public, inherited or private, the
default will be different depending on whether you inherit from a struct or
class. When inheriting from a struct, it will be public inheritance; when
inheriting from a class, it will be private inheritance.
No, it doesn't work that way. It doesn't matter whether the class you are
inheritting from was defined with struct or class. What matters is the key
used to define the derived class.

struct X; // or class X; it doesn't matter

struct Y : X { } ; // Public inheritance
class Y : X { } ; // Private inheritance.

So, if you replaced all "struct"s with "class"es and added "public" access
specifications as necessary to make all access rights equivalent to what
they were before, it is still possible for the meaning of a program to
change. Specifically, some public inheritance might change to private
inheritance, as stated above...


Nope, you just have to make sure you put in enough public keys

struct Y : X { ...
is equivielent to
class Y : public X {
public: ...


Jul 19 '05 #21
Mike Smith wrote:

Alf P. Steinbach wrote:

Thanks, and please pass the word (it's September again).


Isn't it always? ;-)

Yes, but sometimes it's more September than other times. Like in
September.


Brian Rodenborn
Jul 19 '05 #22
> > When inheriting, if you don't specify public, inherited or private, the
default will be different depending on whether you inherit from a struct or class. When inheriting from a struct, it will be public inheritance; when inheriting from a class, it will be private inheritance.
No, it doesn't work that way. It doesn't matter whether the class you

are inheritting from was defined with struct or class. What matters is the key used to define the derived class.

struct X; // or class X; it doesn't matter

struct Y : X { } ; // Public inheritance
class Y : X { } ; // Private inheritance.

So, if you replaced all "struct"s with "class"es and added "public" access specifications as necessary to make all access rights equivalent to what
they were before, it is still possible for the meaning of a program to
change. Specifically, some public inheritance might change to private
inheritance, as stated above...


Nope, you just have to make sure you put in enough public keys

struct Y : X { ...
is equivielent to
class Y : public X {
public: ...


Oh geez, you are absolutely right. Public vs. private by default depends on
the derived class, not the base class. 11.2.2 spells this out...

Thx for setting it straight!

Jul 19 '05 #23

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

Similar topics

12
by: Tim Clacy | last post by:
Your expertise will be appreciated... Here's a general templatised class; all specialisations of this class should have a pointer to a specialisation of the same, templatised type: ...
8
by: Dave | last post by:
class base { public: base(const base &other) { // Init. here... } // Stuff }; class derived: public base { public:
3
by: Markus Dehmann | last post by:
I have a two different value types with which I want to do similar things: store them in the same vector, stack, etc. Also, I want an << operator for each of them. class Value{}; // this would...
6
by: Paul | last post by:
In real life situation, do we ever come across a situation where we would need two base objects in an object. A snippet is worth 1000 words (: so... class Base { }; class Derived1:public Base...
5
by: Fernando Cacciola | last post by:
Hi people, I'm testing Microsoft Visual Studio 2005 Version 8.0.50727.42 (RTM.050727-4200) with our code base. I'm getting lots of errors on code that compiled fine in 7.1.
4
by: michael.alexeev | last post by:
Hi all. Consider the following code fragment: #include <string> struct Base{ virtual ~Base() {} }; template <typename T> struct Derived : public Base {}; Base* Create (int param) { switch...
5
by: Dimitry | last post by:
I am trying to make the following: struct Base { char param; }; class Derived1 : public Base { public:
2
by: Ninereeds | last post by:
I'm messing around with using mixin-layers (look for papers by Yannis Smaragdakis and Don Batory) to define data structures. One issue is that nodes tend to have pointers to other nodes - the...
15
by: Juha Nieminen | last post by:
I'm sure this is not a new idea, but I have never heard about it before. I'm wondering if this could work: Assume that you have a common base class and a bunch of classes derived from it, and...
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
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,...
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
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...
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...
0
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,...
0
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...

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.