473,327 Members | 1,936 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,327 software developers and data experts.

Empty base class (like Java's "interface")?

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 be "public interface Value{}" in Java!

class IntValue : public Value{
private:
int _value;
public:
IntValue(int value):_value(value){}
};

class StringValue : public Value{ // constructor etc omitted
private:
std::string _value;
public:
StringValue(std::string value):_value(value){}
};

But how do I realize the << operator? I could do sth like this, then:

int main(){
vector <Value> val;
values.push_back(IntValue(3));
values.push_back(StringValue("test"));
for ( vector<Value>::iterator it = val.begin(); it != val.end();
++it ){
cout << *it;
}
}

I tried defining it empty in the base class and with a non-empty
implementation in IntValue and StringValue, but it gives me compile
errors (can't find the operator)

class Value{
std::ostream & operator<<(std::ostream & out){}
};

So, how can I do it?

Thanks
Marks
Jul 22 '05 #1
3 3571
"Markus Dehmann" <ma*******@gmx.de> wrote...
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 be "public interface Value{}" in Java!
No, it wouldn't. You need at least a virtual destructor.
class IntValue : public Value{
private:
int _value;
public:
IntValue(int value):_value(value){}
};

class StringValue : public Value{ // constructor etc omitted
private:
std::string _value;
public:
StringValue(std::string value):_value(value){}
};

But how do I realize the << operator? I could do sth like this, then:

int main(){
vector <Value> val;
values.push_back(IntValue(3));
This is nonsense. Read about 'slicing' and 'heterogenous containers'.
In short, if you attempt to stor 'IntValue' in a vector<Value>, you
will store only the base part of the 'IntValue' and lose all of its
identity. Store pointers.
values.push_back(StringValue("test"));
for ( vector<Value>::iterator it = val.begin(); it != val.end();
++it ){
cout << *it;
}
}

I tried defining it empty in the base class and with a non-empty
implementation in IntValue and StringValue, but it gives me compile
errors (can't find the operator)

class Value{
std::ostream & operator<<(std::ostream & out){}
};

So, how can I do it?


Google the newsgroup archives. Has been done before, has been written
about dozens of times. No need to repeat.

V
Jul 22 '05 #2

"Markus Dehmann" <ma*******@gmx.de> wrote in message
news:c1**************************@posting.google.c om...
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 be "public interface Value{}" in Java!

class IntValue : public Value{
private:
int _value;
public:
IntValue(int value):_value(value){}
};

class StringValue : public Value{ // constructor etc omitted
private:
std::string _value;
public:
StringValue(std::string value):_value(value){}
};

But how do I realize the << operator? I could do sth like this, then:

int main(){
vector <Value> val;
values.push_back(IntValue(3));
values.push_back(StringValue("test"));
for ( vector<Value>::iterator it = val.begin(); it != val.end();
++it ){
cout << *it;
}
}

I tried defining it empty in the base class and with a non-empty
implementation in IntValue and StringValue, but it gives me compile
errors (can't find the operator)

class Value{
std::ostream & operator<<(std::ostream & out){}
};

So, how can I do it?


Buy a book on C++, look up the chapter on polymorphism and virtual
functions. Also don't try to program C++ by analogy with Java, you'll end up
programming only the common ground between Java and C++ which won't get you
very far. Here's some untested sample code

class Value
{
public:
virtual ~Value() {}
virtual void print(ostream& os) const = 0;
};

class IntValue : public Value{
private:
int _value;
public:
IntValue(int value):_value(value){}

void print(ostream& os) const
{
os << _value;
}
};

class StringValue : public Value{ // constructor etc omitted
private:
std::string _value;
public:
StringValue(std::string value):_value(value){}

void print(ostream& os) const
{
os << _value;
}
};

std::ostream & operator<<(std::ostream & out, const Value& x)
{
x.print(out);
return out;
}

And of course like Victor says, you must store pointers or smart pointers in
your vector. Try googling for smart pointer, or check out shared_ptr at
www.boost.org

john
Jul 22 '05 #3
Markus Dehmann wrote:
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.
OK, templates and the whole STL is designed to support this sort of thing.
class Value{}; // this would be "public interface Value{}" in Java!
As Victor said, not really. In C++, you rarely need empty interfaces.
If your reason for creating a common base class is to express a set of
operations common to different sub-classes, why is the base empty?
class IntValue : public Value{
private:
int _value;
public:
IntValue(int value):_value(value){}
};
#include <string>
class StringValue : public Value{ // constructor etc omitted
private:
std::string _value;
public:
StringValue(std::string value):_value(value){}
};

But how do I realize the << operator? I could do sth like this, then:
#include <iostream>
#include <vector>
int main(){
using namespace std;
vector <Value> val;
values.push_back(IntValue(3));
Is "values" supposed to be the same object as "val"?
values.push_back(StringValue("test"));
for ( vector<Value>::iterator it = val.begin(); it != val.end();
++it ){
cout << *it;
}
}

I tried defining it empty in the base class and with a non-empty
implementation in IntValue and StringValue, but it gives me compile
errors (can't find the operator)

class Value{
std::ostream & operator<<(std::ostream & out){}
};
You're close. This would define a way to insert the stream into the
Value, rather than the other way around. Probably not what you want. ;)
So, how can I do it?


Define the operator as a free-standing function, and have it call a
print method declared in the base class.
You might want to adjust your viewpoint a bit when programming in C++.
When you consider a data type or operation, keep it as generic as
possible. Instead of defining two wrapper classes that are identical
except for the type of value they wrap, define a class template for such
wrappers. Instead of looping over the contents of a container (which
you are likely to do pretty frequently), use the existing library
facilities, and only write new code to represent the new or original
part of your program (not the looping code). You'll end up with lots of
short blocks and classes; it will feel inefficient, because you'll be
producing a lot of "overhead" code (class declarations and the like) for
each simple operation. However, the savings you will get in the long
term, not only in development time but in maintenance, might just
impress you so much with C++ that you find yourself using it for almost
everything.

Here's an example of one way to write something like the code above.
I've used explicit dynamic allocation, to match what I think you're
trying to do. Notice that the memory has to be deleted manually.

One other thing worth mentioning is that I already have built a library
of utility classes like Dereferencer and Deleter below, so I don't have
to redefine them every time I use them. If you're new to C++, but
already know a different language, this is probably a good time to start
building your own library of utilities.

#include <iosfwd>

struct Value_base
{
virtual ~Value_base ( ) { }
virtual void print ( std::ostream& ) const =0;
};

template< typename T >
struct Value: public Value_base
{
Value ( T const& t = T( ) ): m_t( t ) { }
void print ( std::ostream& out ) const { out << m_t; }
private:
T m_t;
};

std::ostream& operator << ( std::ostream& out, Value_base const& v )
{
v.print( out );
return out;
}

struct Dereferencer
{
template< typename T >
T const& operator ( ) ( T const* p ) const { return *p; }
};

struct Deleter
{
template< typename T >
void operator ( ) ( T const* p ) const { delete p; }
};

#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <string>
#include <vector>

int main ( )
{
typedef std::vector< Value_base* > Vector;

Vector values;

values.push_back( new Value< int >( 3 ) );
values.push_back( new Value< std::string >( "test" ) );

std::ostream_iterator< Value_base > out( std::cout, "\n" );
Dereferencer deref;

std::transform( values.begin( ), values.end( ), out, deref );

std::for_each( values.begin( ), values.end( ), Deleter( ) );
}
Jul 22 '05 #4

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

Similar topics

5
by: BoonHead, The Lost Philosopher | last post by:
Does anyone know how to implement internal interface documentation for functions and parameters? I found a similair thing for proerties. For properties I found something like:...
0
by: Rex | last post by:
Hello... I have a C# app, and am trying to save a web page as a .mht file using CreateMHTMLBody. It was working a while back, but now I am getting "interface not registered" errors when calling...
2
by: seesaw | last post by:
When define an interface of all pure virtual functions, will the destructor of it will automatically virtual, or it has to be declared as virtual? Should it be declared as "virtual" when defining...
1
by: n_o_s_p_a__m | last post by:
My web service has a webmethod whose return type is declared as an interface type, for example: public IBusinessProcess GetBusinessProcess() {} which generates the lovely error: Cannot...
11
by: Antony | last post by:
I know this sounds stupid but I am going to carry on anyway. I want to create an interface that implements all methods of a form, plus another one or two. But I need to know if there is an...
0
by: Dundealing | last post by:
I am trying to deploy an application but when I build it in Release mode, I get the message: "Could not find file '<pathname>\appname.exe' Interface not registered". It works fine in Debug...
0
by: Kivak Wolf | last post by:
Hey, Not sure how to explain this. But I created a SQL server database file called "testingData.mdf" using VS2005 and I connected to it. After I create it, I can modify it, connect things to it...
2
by: VolkerS | last post by:
Hallo, I need helping adding an existing Interface to an object I dispatched from a COM-server via win32com in Python. The Code for this in VisualBasic looks like that: Private Obj_1 As...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.