473,394 Members | 1,722 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.

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 1565

"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: DefaultConstructable concept that is required by
say std::vector<>.

The problem though I see is the conflicting requirements.
DefaultConstructible 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...@yahoo.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: DefaultConstructable 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.
DefaultConstructible 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*********@yahoo.comwrote in message
news:Rw*****************@newssvr17.news.prodigy.ne t...
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
Dennis Jones wrote:
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.
You can simply drop the data element:

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

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

--
Salu2
Feb 10 '07 #11

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

Similar topics

2
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...
5
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...
3
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...
2
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...
6
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...
7
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
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...
7
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...
7
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...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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?
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...

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.