473,811 Members | 2,691 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Putting a constant member in a base

Hello,

I have a hierarchy of classes in which there will be a data element that is
common to all descendant classes. This element (a string in this case) is
constant, but specific to each class. So I have something like this:

class Base
{
private:
virtual std::string GetString() const = 0;
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
private:
const std::string FString;
virtual std::string GetString() const { return FString; }
public:
Derived()
: Base(),
FString( "Derived" ) {}
};

This isn't completely unreasonable, but I do have to duplicate the 'FString'
data element and its getter function in every derived class. It would be
much nicer if I could do something like this instead:

class Base
{
private:
const std::string FString;
std::string GetString() const { return FString; }
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
public:
Derived()
: Base(),
FString( "Derived" ) {}
};

However, this won't work because the compiler will complain that "'FString'
is not an unabiguous base class of 'Derived'" which, of course, is true and
makes perfect sense. A less desirable (but still reasonable) solution would
be to initialize 'FString' in the constructor's body:

class Derived : public Base
{
public:
Derived()
: Base()
{
FString = "Derived";
}
};

But of course, this won't work either because 'FString' is const! What's
one to do? Is there a way to eliminate the unnecessary duplication and
maintain the constness of the data element at the same time?

Thanks,

- Dennis
Feb 10 '07 #1
10 1603

"Dennis Jones" <no****@nospam. comwrote in message
news:ud9zh.140$ II6.87@trnddc07 ...
Hello,

I have a hierarchy of classes in which there will be a data element that
is common to all descendant classes. This element (a string in this case)
is constant, but specific to each class. So I have something like this:

class Base
{
private:
virtual std::string GetString() const = 0;
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
private:
const std::string FString;
virtual std::string GetString() const { return FString; }
public:
Derived()
: Base(),
FString( "Derived" ) {}
};

This isn't completely unreasonable, but I do have to duplicate the
'FString' data element and its getter function in every derived class. It
would be much nicer if I could do something like this instead:

class Base
{
private:
const std::string FString;
std::string GetString() const { return FString; }
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
public:
Derived()
: Base(),
FString( "Derived" ) {}
};

However, this won't work because the compiler will complain that
"'FString' is not an unabiguous base class of 'Derived'" which, of course,
is true and makes perfect sense. A less desirable (but still reasonable)
solution would be to initialize 'FString' in the constructor's body:

class Derived : public Base
{
public:
Derived()
: Base()
{
FString = "Derived";
}
};

But of course, this won't work either because 'FString' is const! What's
one to do? Is there a way to eliminate the unnecessary duplication and
maintain the constness of the data element at the same time?

P.S. I should have mentioned that due to my employer's preferences, using a
constructor argument (as shown below) is not desirable, which is why I am
searching for other alternatives:

class Base
{
private:
const std::string FString;
std::string GetString() const { return FString; }
public:
Base( const std::string &AString )
: FString( AValue ) {}
void SomeFunction() { GetString(); }
};
Thanks,
- Dennis
Feb 10 '07 #2
Dennis Jones wrote:
Hello,

I have a hierarchy of classes in which there will be a data element that is
common to all descendant classes. This element (a string in this case) is
constant, but specific to each class. So I have something like this:

class Base
{
private:
virtual std::string GetString() const = 0;
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
private:
const std::string FString;
virtual std::string GetString() const { return FString; }
public:
Derived()
: Base(),
FString( "Derived" ) {}
};

This isn't completely unreasonable, but I do have to duplicate the 'FString'
data element and its getter function in every derived class. It would be
much nicer if I could do something like this instead:

class Base
{
private:
const std::string FString;
std::string GetString() const { return FString; }
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
public:
Derived()
: Base(),
FString( "Derived" ) {}
};

However, this won't work because the compiler will complain that "'FString'
is not an unabiguous base class of 'Derived'" which, of course, is true and
makes perfect sense. A less desirable (but still reasonable) solution would
be to initialize 'FString' in the constructor's body:

class Derived : public Base
{
public:
Derived()
: Base()
{
FString = "Derived";
}
};

But of course, this won't work either because 'FString' is const! What's
one to do? Is there a way to eliminate the unnecessary duplication and
maintain the constness of the data element at the same time?

Thanks,

- Dennis

I am not sure I understand what you are looking for but
by any chance you are looking for this?

class Base
{
private:
const std::string FString;
std::string GetString() const { return FString; }
public:
Base( const std::string &val ) : FString( val ) {}
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
public:
Derived()
: Base( "Derived" ) {}
// for ease of use to change the value to something else
Derived( const std::string &val ) : Base(val) {}
};

Hope that helps!
Feb 10 '07 #3
Dennis Jones wrote:
>
P.S. I should have mentioned that due to my employer's preferences, using a
constructor argument (as shown below) is not desirable, which is why I am
searching for other alternatives:
Well that's just plain daft. Ask them to give a good reason why this is so.

--
Ian Collins.
Feb 10 '07 #4
Piyo wrote:
Dennis Jones wrote:
>Hello,

I have a hierarchy of classes in which there will be a data element
that is common to all descendant classes. This element (a string in
this case) is constant, but specific to each class. So I have
something like this:

class Base
{
private:
virtual std::string GetString() const = 0;
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
private:
const std::string FString;
virtual std::string GetString() const { return FString; }
public:
Derived()
: Base(),
FString( "Derived" ) {}
};

This isn't completely unreasonable, but I do have to duplicate the
'FString' data element and its getter function in every derived
class. It would be much nicer if I could do something like this instead:

class Base
{
private:
const std::string FString;
std::string GetString() const { return FString; }
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
public:
Derived()
: Base(),
FString( "Derived" ) {}
};

However, this won't work because the compiler will complain that
"'FString' is not an unabiguous base class of 'Derived'" which, of
course, is true and makes perfect sense. A less desirable (but still
reasonable) solution would be to initialize 'FString' in the
constructor' s body:

class Derived : public Base
{
public:
Derived()
: Base()
{
FString = "Derived";
}
};

But of course, this won't work either because 'FString' is const!
BTW, not only is it not possible because it is const but FString is
private and the derived class cannot access private members of the base.

Having said that:

Try this?

class Base
{
private:
// remove const, your derived classes cannot touch it
std::string FString;
std::string GetString() const { return FString; }
protected:
// allow derived class to set it
void setFString( const std::string &val ) { FString = val; }
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
public:
Derived()
: Base() { setFString( "Derived" ); }
// for ease of use to change the value to something else
Derived( const std::string &val ) : Base() { setFString(val) ;}
};

Does that work for you?
Feb 10 '07 #5
Ian Collins wrote:
Dennis Jones wrote:
>P.S. I should have mentioned that due to my employer's preferences, using a
constructor argument (as shown below) is not desirable, which is why I am
searching for other alternatives:
Well that's just plain daft. Ask them to give a good reason why this is so.
LOL :) daft :) XD

Feb 10 '07 #6
Ian Collins wrote:
Dennis Jones wrote:
>P.S. I should have mentioned that due to my employer's preferences, using a
constructor argument (as shown below) is not desirable, which is why I am
searching for other alternatives:
Well that's just plain daft. Ask them to give a good reason why this is so.
Ok all joking aside, Here is a good reason why you do not want to have a
constructor argument: DefaultConstruc table concept that is required by
say std::vector<>.

The problem though I see is the conflicting requirements.
DefaultConstruc tible vs const initialization. A const member variable
cannot be initialized except via the constructor's member
initialization. Otherwise, the const member function will simply always
be its default value.

Feb 10 '07 #7
On Feb 9, 7:56 pm, Piyo <cybermax...@ya hoo.comwrote:
Ian Collins wrote:
Dennis Jones wrote:
P.S. I should have mentioned that due to my employer's preferences, using a
constructor argument (as shown below) is not desirable, which is why I am
searching for other alternatives:
Well that's just plain daft. Ask them to give a good reason why this is so.

Ok all joking aside, Here is a good reason why you do not want to have a
constructor argument: DefaultConstruc table concept that is required by
say std::vector<>.
True indeed. But if the hypothetical base class has pure virtual
functions it'd also be impossible to use it in an stl container (as
anything other than a pointer).
>
The problem though I see is the conflicting requirements.
DefaultConstruc tible vs const initialization. A const member variable
cannot be initialized except via the constructor's member
initialization. Otherwise, the const member function will simply always
be its default value.
I don't have a copy of the standard but it makes sense that the only
class able to initialize a member variable is the one in which it is
defined. (IE, a class can't initialze an inherited member variable).

And like the parent poster noted, this is a const initialization vs.
default constructable question.

So I'd probably work on convincing your boss that discarding the
option of constructor arguments out of hand is silly. Especially if
that base class has pure virtual methods.

HTH,
Paul Davis

Feb 10 '07 #8

"Piyo" <cy*********@ya hoo.comwrote in message
news:Rw******** *********@newss vr17.news.prodi gy.net...
class Base
{
private:
// remove const, your derived classes cannot touch it
std::string FString;
std::string GetString() const { return FString; }
protected:
// allow derived class to set it
void setFString( const std::string &val ) { FString = val; }
public:
void SomeFunction() { GetString(); }
};

class Derived : public Base
{
public:
Derived()
: Base() { setFString( "Derived" ); }
// for ease of use to change the value to something else
Derived( const std::string &val ) : Base() { setFString(val) ;}
};

Does that work for you?
Yes, a setter with a private member just might be what the doctor ordered.

- Dennis
Feb 10 '07 #9
"Dennis Jones" <no****@nospam. comwrote in message
news:5o9zh.141$ II6.5@trnddc07
>
P.S. I should have mentioned that due to my employer's preferences,
using a constructor argument (as shown below) is not desirable, which
is why I am searching for other alternatives:

class Base
{
private:
const std::string FString;
std::string GetString() const { return FString; }
public:
Base( const std::string &AString )
: FString( AValue ) {}
void SomeFunction() { GetString(); }
};

Perhaps there is some reason for this "preference " but, on the face of
things, your employer is an idiot.

--
John Carson

Feb 10 '07 #10

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

Similar topics

2
6524
by: srinivas reddy | last post by:
Hi, Can a constant member function be overloaded with its non-constant equivalent. I mean can void func() be overloaded with void func() const. If so what behaviour is guaranteed, how does the compiler resolve ambiguity?, and how could I call a specific variant? tia, Srinivas
5
4838
by: CoolPint | last post by:
It seems to me that I cannot assign objects of a class which has a constant data member since the data member cannot be changed once the constructor calls are completed. Is this the way it is meant to be? Am I not suppose not to have any constant data member if I am going to have the assignment operator working for the class? Or am I missing something here and there is something I need to learn about? Clear, easy to understand...
3
12121
by: Roy Yao | last post by:
Hello, I need to pass a pointer to a callback function to the lower level modules. But the function is thought to be a virtual member one. How can I get the real address of the virtual member function?
2
4673
by: Bob | last post by:
The line Thread.CurrentThread.Sleep(intRetryInterval) in 2005 (worked OK in 2003, I think) gives me a warning that Access of Shared Member, Constant Member, enum member or nested type through an instance, qualifying expression will not be evaluated. OK I agree, so now what? I just want to put this thread to sleep for 10 milliseconds.
6
2262
by: DaTurk | last post by:
Hi, I'm a bit rusty with the wonderful language of c++. I worked with it, maybe 6 or 7 years ago and now I need to knock the dust off. But I was perusing some code when I noticed that this one programmer put the entire class in the header file. I'm not sure what the point to that is. Can someone please enlighten me as to why you would want to do this? And if you do want to, what are the pro's and cons of doing it. Are
7
3818
by: WaterWalk | last post by:
Hello. I thought I understood member function pointers, but in fact I don't. Consider the following example: class Base { public: virtual ~Base() {} }; class Derived : public Base {
4
1331
by: Gordon | last post by:
I'm trying to get a constant from a class, where the constant's name is known, but the class name isn't. I want to do things this way because I want classes to be able to define certain aspects for their setup themselves. For example: I have a situation where I have a script that can deal with objects of one of several classes, but each class needs some slightly different setup parameters. I'm currently taking care of this with a...
7
2817
by: John Koleszar | last post by:
Hi all, I'm porting some code that provides compile-time assertions from one compiler to another and ran across what I believe to be compliant code that won't compile using the new compiler. Not naming names here to remove bias - I'm trying to tell if I'm relying on implementation defined behavior or if this is a bug in the new compiler. Consider this stripped down example:
7
4274
by: Hendrik Schober | last post by:
Hi, this #include <string> class test { typedef std::string::size_type size_type; static const size_type x = std::string::npos; }; doesn't compile using either VC9 ("expected constant expression") or Comeau Online ("constant value is not known"). If I replace
0
9728
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
9605
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
10648
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. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10389
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
10135
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...
0
9205
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 launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6890
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
5554
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
5692
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.