473,785 Members | 3,349 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Which would you prefer: base class or two pointers?

I have the following situation:

Given this class:
template<typena me T>
class Expression {
/* omitted */
};

This is the base class for a BooleanExpressi on and an ArithmeticExpre ssion.

Now I have another struct, that contains a BooleanExpressi on and an
ArithmeticExpre ssion. This expression will be either Expression<int> or
Expression<stri ng>. Which one is determined at runtime. The problem I'm
faced with is how to store them. Basically, I'm leaning toward two different
options.

1. Create a base class BaseExpression, that doesn't really do anything at
all, and have Expression inherit from it, making the other class like this:
struct MatchModifier
{
BaseExpression *test;
BaseExpression *operation;
};

I'll have a flag somewhere that I'll need to have anyway that'll tell me the
type it's going to be, so I could then dynamic_cast them whenever I need to
use them.

2. Just have two pointers, only one of which is used:
struct MatchModifier
{
BooleanExpressi on<int> *intTest;
BooleanExpressi on<std::string> *stringTest;
ArithmeticExpre ssion *intOperation;
std::string *stringOperatio n;
};

As you can see here, there's not actually an
ArithmeticExpre ssion<std::stri ng>, it'll just be a plain string.

From my perspective, option two holds the best cards. It clearly relates the
fact that test is always a BooleanExpressi on and that operation is always an
ArithmeticExpre ssion (or string constant). It also means I don't need to
create an additional class that has no real purpose, and I won't need to
create a StringConstant class or whatever that inherits from BaseExpression
to wrap the std::string. It's also more performant (I think) as the
expressions will be used often, and for option 1 that means a dynamic_cast
every single time, and option 2 just involves picking one of two pointers.
Option 2 does waste 8 bytes per MatchModifier, but that's not such a big
problem, and I could always use unions if that really becomes a concern.
Option 2 does have the distinct disadvantage that adding additional
Expression types adds more work, but at this time it doesn't seem likely
that that'll happen.

However, somehow my sense of style has a little voice in my head saying that
option 2 is wrong somehow, that there must be a more elegant solution. But
all I can come up with is solution 1.

So, which would you prefer. Or would you perhaps know a better, third
alternative?

Thanks in advance for any input.

--
Unforgiven

Jul 22 '05 #1
3 1390
I would lean toward utilizing the C++ type matching system over doing explicit
casts if at all possible. Yes this means more work up-front and a little extra
effort when you add new types... but when you start maintaining it the extra
up-front work will pay off big-time.

David

Unforgiven wrote:
I have the following situation:

Given this class:
template<typena me T>
class Expression {
/* omitted */
};

This is the base class for a BooleanExpressi on and an ArithmeticExpre ssion.

Now I have another struct, that contains a BooleanExpressi on and an
ArithmeticExpre ssion. This expression will be either Expression<int> or
Expression<stri ng>. Which one is determined at runtime. The problem I'm
faced with is how to store them. Basically, I'm leaning toward two different
options.

1. Create a base class BaseExpression, that doesn't really do anything at
all, and have Expression inherit from it, making the other class like this:
struct MatchModifier
{
BaseExpression *test;
BaseExpression *operation;
};

I'll have a flag somewhere that I'll need to have anyway that'll tell me the
type it's going to be, so I could then dynamic_cast them whenever I need to
use them.

2. Just have two pointers, only one of which is used:
struct MatchModifier
{
BooleanExpressi on<int> *intTest;
BooleanExpressi on<std::string> *stringTest;
ArithmeticExpre ssion *intOperation;
std::string *stringOperatio n;
};

As you can see here, there's not actually an
ArithmeticExpre ssion<std::stri ng>, it'll just be a plain string.

From my perspective, option two holds the best cards. It clearly relates the
fact that test is always a BooleanExpressi on and that operation is always an
ArithmeticExpre ssion (or string constant). It also means I don't need to
create an additional class that has no real purpose, and I won't need to
create a StringConstant class or whatever that inherits from BaseExpression
to wrap the std::string. It's also more performant (I think) as the
expressions will be used often, and for option 1 that means a dynamic_cast
every single time, and option 2 just involves picking one of two pointers.
Option 2 does waste 8 bytes per MatchModifier, but that's not such a big
problem, and I could always use unions if that really becomes a concern.
Option 2 does have the distinct disadvantage that adding additional
Expression types adds more work, but at this time it doesn't seem likely
that that'll happen.

However, somehow my sense of style has a little voice in my head saying that
option 2 is wrong somehow, that there must be a more elegant solution. But
all I can come up with is solution 1.

So, which would you prefer. Or would you perhaps know a better, third
alternative?

Thanks in advance for any input.

--
Unforgiven

Jul 22 '05 #2
"Unforgiven " <ja*******@hotm ail.com> wrote in message
news:2s******** *****@uni-berlin.de...
I have the following situation:

Given this class:
template<typena me T>
class Expression { This is the base class for a BooleanExpressi on and an ArithmeticExpre ssion.
struct MatchModifier
{
BaseExpression *test;
BaseExpression *operation;
};

I'll have a flag somewhere that I'll need to have anyway that'll tell me the type it's going to be, so I could then dynamic_cast them whenever I need to use them. struct MatchModifier
{
BooleanExpressi on<int> *intTest;
BooleanExpressi on<std::string> *stringTest;
ArithmeticExpre ssion *intOperation;
std::string *stringOperatio n;
};


Is it possible to have a 3 level system?

class Expression { ... };
class BooleanExpressi on : public Expression { ... };
class ArithmeticExpre ssion : public Expression { ... };
template<typena me T> class ConcreteBoolean Expression : public
BooleanExpressi on { ... };
template<typena me T> class ConcreteArithme ticExpression : public
ArithmeticExpre ssion { ... };

Turn MatchModifier into a class to control access to it. The public
functions will have to ensure that 'test' and 'operation' are for the same
underlying type. The destructor and copy constructor and operator== shall
delete and clone the expressions.

class MatchModifier
{
private:
BooleanExpressi on *d_test;
ArithmeticExpre ssion *d_operation;
public:
MatchModifier(s td::auto_ptr<Bo oleanExpression >,
std::auto_ptr<A rithmeticExpres sion>);
MatchModifier(c onst MatchModifier&) ;
MatchModifier& operator=(const MatchModifier&) ;
~MatchModifier( );
};

MatchModifier:: MatchModifier(s td::auto_ptr<Bo oleanExpression >,
std::auto_ptr<A rithmeticExpres sion>)
: d_test(test.rel ease()), d_operation(ope ration.release( ))
{
if (test->underlying_typ eid() != operation->underlying_typ eid())
{
throw ...;
}
}
Jul 22 '05 #3
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote in message
news:bn******** *************@b gtnsc05-news.ops.worldn et.att.net...
Is it possible to have a 3 level system?

class Expression { ... };
class BooleanExpressi on : public Expression { ... };
class ArithmeticExpre ssion : public Expression { ... };
template<typena me T> class ConcreteBoolean Expression : public
BooleanExpressi on { ... };
template<typena me T> class ConcreteArithme ticExpression : public
ArithmeticExpre ssion { ... };


I already thought about that but unfortunately no, since there's some common
code in Expression that's already templated.

--
Unforgiven

Jul 22 '05 #4

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

Similar topics

5
11340
by: Bob Hairgrove | last post by:
Consider the following: #include <string> class A { public: A( const std::string & full_name , const std::string & display_name) : m_full_name(full_name)
4
2173
by: Joel | last post by:
I have this bug that quite puzzled me. Basically I am having a segmentation fault on deleting an object, which belongs to a class which is the result of multiple inheritance from two other classes. None of the classes actually allocate memory on the heap. I simplified my code into one piece to show below. I will really appreciate if someone can tell me where the problem is. I have spent quite some time on it and felt a bit lost at this...
4
2713
by: Alfonso Morra | last post by:
Hi, I have a variable that stores a pointer to a base class. I am using this variable to store pointers to objects of the base class, as well as pointers to other derived classes. However, the derived classes have methods (not available on the base class) that I would like to invoke. I thought I could simply cast the pointer to the appropriate derived class and access the methods this way - but that dosen't work.
10
3334
by: Bhan | last post by:
Using Ptr of derived class to point to base class and viceversa class base { .... } class derived : public base { .... }
5
1962
by: Michael | last post by:
Hi, Could you tell me whether the following two statement are the same? Derived class is derived from Base class. 1. Base* ptr1; 2. Derived * ptr2; Does it mean ptr1 is the same as ptr2?
5
3456
by: Scott | last post by:
Hi All, Am I correct in assuming that there is no way to have a base pointer to an object that uses multiple inheritance? For example, class A { /* ... */ }; class B { /* ... */ };
1
2212
by: manontheedge | last post by:
can someone clarify what base class pointers are for me. I know what Inheritence is and how abstract base classes work with derived classes, but i'm a little lost on base class pointers. I don't know why i'm not getting it. what i'm trying to do is have one class contain base class pointers to each derived class ( of another base class ) ... and at this point i'm just confused and i'm not sure how to go about it. I looked around on the...
12
2724
by: subramanian100in | last post by:
Suppose class Base { public: virtual ~Test() { ... } // ... }; class Derived : public Base
1
2527
by: Rune Allnor | last post by:
Hi all. I am sure this is an oldie, but I can't find a useful suggestion on how to solve it. I have a class hierarchy of classes derived from a base class. I would like to set up a vector of smart pointers to the base class, and access the virtual functions of any class in the hierarchy through the virtual functions.
0
9643
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 usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9480
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 synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10147
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 captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9947
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 choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7496
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 instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6737
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5380
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 the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5511
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4046
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.