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

Read-only data members

The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now. You can always get
around it with accessor methods that return const references, but
classes with huge lists of accessors often seem awkward/ugly.

So I finally sat down and thought of a syntax I'd like to see as a
fix. I certainly don't expect to ever see it introduced, but it's
interesting to think about.

The syntax is to add a new keyword, "expose", which can only be used
in class declarations. After expose, you redeclare an existing class
member with a greater degree of const-ness, at a different protection
level. It might be necessary to only expose a member after that
member's declaration, but for this example I'll assume you can use it
before:

class Foo {
public:
// public can read the string contents
expose const char* const str;
protected:
// derived classes can modify the string contents
expose char* const str;
private:
// only Foo can change str itself
char* str;
};

My questions for the group are:
1) Would compilers have any problem handling this syntax and its
effects? It seems like it would be relatively easy to handle, but
I don't know all that much about compilers.
2) Are there any flaws with the syntax or its effects? i.e. would it
lead to any ambiguous situations or have undesirable side effects?
3) Do you think that, if this syntax were magically added to C++, it
would be a good/useful thing or a bad/useless thing?

-Dave
Jul 19 '05 #1
14 11337

"David Gausebeck" <ga******@paypal.com> wrote in message
news:3f****************@news.cis.dfn.de...
The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now.


I couldn't understand from your post why "const" doesn't provide read-only
access.
Jul 19 '05 #2
Nice point. I hacked out the code

<David Gausebeck>
class Foo {
public:
// public can read the string contents
expose const char* const str;
protected:
// derived classes can modify the string contents
expose char* const str;
private:
// only Foo can change str itself
char* str;
};
</David Gausebeck>

Expose only works for protected, doesn't it?
In the public section, data is already 'exposed'.
In the private section, there is nothing to expose.
So it dresses up protected. More logical to introduce
a 4th access specifier to handle 'protected' data members.
It must be something starting with a p (I guess). Perhaps
priviliged?

-X
Jul 19 '05 #3
>> The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now.


I couldn't understand from your post why "const" doesn't provide read-only
access.


It does, but not in the way I'm talking about. I realized that line
was unclear, but I couldn't think of a better, concise way to write
it. So I just went on and explained in more detail below. Having
thought about it a little more now, it would be better as:

The inability to denote data members as read-only for public or
protected access is something which has annoyed me (slightly) for a
while now.

-Dave
Jul 19 '05 #4
David Gausebeck wrote:
The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now. You can always get
around it with accessor methods that return const references, but
classes with huge lists of accessors often seem awkward/ugly.
.... -Dave


I think the accessor method technique is exactly the right solution.

The alternative is to make the members themselves "smart members".

This is an example, I'm sure I missed a few important things, I'll let
you fill in the blanks.
class Foo;

template <typename T> class ReadOnlyMember
{
friend class Foo;

public:

operator const T & () const
{
return value;
}

protected:

template <typename T1> const T & operator = ( T1 & vin )
{
value = vin;
return value;
}

ReadOnlyMember( const T & vin )
: value( vin )
{
}

T value;
};
class Foo {
public:
// public can read the string contents
ReadOnlyMember<char*> str1;

// derived classes can modify the string contents
ReadOnlyMember<const char*> str2;

private:
// only Foo can change str itself
char* str3;

public:

Foo()
: str1( "str1" ), str2( "str2" )
{
}

void tester()
{
char xxx[2];
str1 = xxx;
str2 = "BBB";
}

};
int main()
{

Foo f;

const char * xx = f.str1;

f.str2 = "can't do this";
}

Jul 19 '05 #5
>Nice point. I hacked out the code

<David Gausebeck>
class Foo {
public:
// public can read the string contents
expose const char* const str;
protected:
// derived classes can modify the string contents
expose char* const str;
private:
// only Foo can change str itself
char* str;
};
</David Gausebeck>

Expose only works for protected, doesn't it?
It could be used for either protected or private members.
In the public section, data is already 'exposed'.
Yes, anything declared as public couldn't be exposed further.
In the private section, there is nothing to expose.
What do you mean? In the example above, it's a private member that's
being exposed.
So it dresses up protected. More logical to introduce
a 4th access specifier to handle 'protected' data members.
It must be something starting with a p (I guess). Perhaps
priviliged?


Even if it did only apply to protected, a different specifier
(meaning, presumably, protected but readable by public) wouldn't be
sufficient, because it couldn't differentiate degrees of const-ness.
Per the example above, would a 'privileged' char* be accessible to
public as const char* const, or just as char* const?

-Dave
Jul 19 '05 #6

"David Gausebeck" <ga******@paypal.com> wrote in message
news:3f****************@news.cis.dfn.de...
The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now.


I couldn't understand from your post why "const" doesn't provide read-onlyaccess.


It does, but not in the way I'm talking about. I realized that line
was unclear, but I couldn't think of a better, concise way to write
it. So I just went on and explained in more detail below. Having
thought about it a little more now, it would be better as:

The inability to denote data members as read-only for public or
protected access is something which has annoyed me (slightly) for a
while now.


Yes, I see your point.
Jul 19 '05 #7

"Ioannis Vranos" <iv*@nothis.emails.ru> wrote in message
news:3f*********************@read.news.gr.uu.net.. .

I do not think such a feature is badly needed and i also believe that we
must not hurry add non-badly needed features into the language.


Well don't worry - "they" won't be hurrying to add any features "we" ask for
:-)
Jul 19 '05 #8
David Gausebeck wrote:
The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now.


[...]

How about (my C++ is a little rusty so bear with me)

class Foo {
int somePrivateValue;
public:
const int & readOnlyWay;
Foo();
};

Foo::Foo() : readOnlyWay(somePrivateValue) {
somePrivateValue = 10;
}

This provides a public read only accessor to somePrivateValue via the
instance variable readOnlyWay, but the class itself is free to modify
somePrivateValue.

-Peter

Jul 19 '05 #9
"Peter Ammon" <pe*********@rocketmail.com> wrote in message
news:bj**********@news.apple.com...
David Gausebeck wrote:
The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now.


[...]

How about (my C++ is a little rusty so bear with me)

class Foo {
int somePrivateValue;
public:
const int & readOnlyWay;
Foo();
};

Foo::Foo() : readOnlyWay(somePrivateValue) {
somePrivateValue = 10;
}

This provides a public read only accessor to somePrivateValue via the
instance variable readOnlyWay, but the class itself is free to modify
somePrivateValue.

Yeap, that's it. You did it. :-) One could use a const * too. Personally i
prefer data hiding for inside class non-constants.



--
Ioannis

* Programming pages: http://www.noicys.freeurl.com
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net

Jul 19 '05 #10
>David Gausebeck wrote:
The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now.


[...]

How about (my C++ is a little rusty so bear with me)

class Foo {
int somePrivateValue;
public:
const int & readOnlyWay;
Foo();
};

Foo::Foo() : readOnlyWay(somePrivateValue) {
somePrivateValue = 10;
}

This provides a public read only accessor to somePrivateValue via the
instance variable readOnlyWay, but the class itself is free to modify
somePrivateValue.


That's pretty good; I hadn't thought of that. It's still awkward
enough that I'd prefer to use accessor methods, though.

The disadvantages I see are:
1) the accessor reference must have a different name from the variable
to which it provides access.
2) the references will make the object larger (typically 4 bytes each)
3) the reference initializer list must be updated separately, so you
have to edit both a .h and a .cpp to grant access. Further, the
reference initializer list would have to be repeated for every
constructor.

I consider 1) to be the most significant problem... it's the same
reason I'm not entirely happy with accessor methods: they
unnecessarily obfuscate what's really going on. Maybe only a little
bit, but every little bit hurts.

-Dave
Jul 19 '05 #11
Hi!

"David Gausebeck" <ga******@paypal.com> wrote in message
news:3f****************@news.cis.dfn.de...

The inability to denote data members as read-only for public or
protected access is something which has annoyed me (slightly) for a
while now.


Put the variables in private section, and add const references in the
public section for all variables that you want to expose:

class C
{
private:
int i;
char *p;

public:
int const &expose_i;
char * const &expose_p;

// etc...
};

BTW, this is actually an argument for making the declaration
level initializer legal for [at least] reference members, like it is
already for static members. If the initializer was allowed to be
present in the class declaration, as shown below...

public:
int const &expose_i = i;
char * const &expose_p = p;

.... then the compiler could optimize the references away from
the run-time manifestation of the object altogether, since all users
of the class would have to include the class declaration anyway,
and all translation units would therefore know at all times what
actual data item the reference will alias. Since this could not
vary, it would not need to be stored in the object itself.

Cheers!

- Risto -

Jul 19 '05 #12
On Thu, 04 Sep 2003 21:31:06 GMT, David Gausebeck wrote:
The inability to denote data members as read-only in C++ is something
which has annoyed me (slightly) for a while now. You can always get
around it with accessor methods that return const references, but
classes with huge lists of accessors often seem awkward/ugly.

So I finally sat down and thought of a syntax I'd like to see as a
fix. I certainly don't expect to ever see it introduced, but it's
interesting to think about.

The syntax is to add a new keyword, "expose", which can only be used
in class declarations. After expose, you redeclare an existing class
member with a greater degree of const-ness, at a different protection
level. It might be necessary to only expose a member after that
member's declaration, but for this example I'll assume you can use it
before:

class Foo {
public:
// public can read the string contents
expose const char* const str;
protected:
// derived classes can modify the string contents
expose char* const str;
private:
// only Foo can change str itself
char* str;
};

My questions for the group are:
1) Would compilers have any problem handling this syntax and its
effects? It seems like it would be relatively easy to handle, but
I don't know all that much about compilers.
2) Are there any flaws with the syntax or its effects? i.e. would it
lead to any ambiguous situations or have undesirable side effects?
3) Do you think that, if this syntax were magically added to C++, it
would be a good/useful thing or a bad/useless thing?

-Dave


I think that the an accessor method offer an advantage: it isolate class
interface from attributes implementation.

You now use a char* to the str attribute but tomorrow maybe you want to use
a stl string and then you will have a problem with your str 'direct
exposition'.

Now : const char* GetStr() const { return str; }
Tomorrow : const char* GetStr() const { return str.c_str(); }

-Arbesto
Jul 19 '05 #13
"Risto Lankinen" <rl******@hotmail.com> wrote in message
news:Yh*******************@news1.nokia.com...

Put the variables in private section, and add const references in the
public section for all variables that you want to expose:

class C
{
private:
int i;
char *p;

public:
int const &expose_i;
char * const &expose_p;

// etc...
};

BTW, this is actually an argument for making the declaration
level initializer legal for [at least] reference members, like it is
already for static members. If the initializer was allowed to be
present in the class declaration, as shown below...

public:
int const &expose_i = i;
char * const &expose_p = p;

... then the compiler could optimize the references away from
the run-time manifestation of the object altogether, since all users
of the class would have to include the class declaration anyway,
and all translation units would therefore know at all times what
actual data item the reference will alias. Since this could not
vary, it would not need to be stored in the object itself.

Since there is a reference for every object you create, why it would be able
to optimise the references away and why it cannot do it while using a
constructor? Providing the above ability seems to me that two ways of object
construction would be provided complicating the construction/destruction
rules.

Using constructors we have simple rules and much control on the construction
of an object.



--
Ioannis

* Programming pages: http://www.noicys.freeurl.com
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net

Jul 19 '05 #14
Hi!

"Ioannis Vranos" <iv*@nothis.emails.ru> wrote in message
news:3f*********************@read.news.gr.uu.net.. .
"Risto Lankinen" <rl******@hotmail.com> wrote in message
news:Yh*******************@news1.nokia.com...

If the initializer was allowed to be
present in the class declaration, as shown below...

public:
int const &expose_i = i;
char * const &expose_p = p;

... then the compiler could optimize the references away from
the run-time manifestation of the object altogether, ...
Since there is a reference for every object you create, why it would be

able to optimise the references away and why it cannot do it while using a
constructor?


The compiler could, for every dereference of 'expose_i'
simply compile a dereference of 'i' without having to store
the actual reference into the object itself. This can take
place in any compilation unit that includes the class header
containing the hypothetical initializer. This optimization
will be robust only if all compilation units implement it
identically (e.g. no other compilation parameter, such as
an optimization-level switch, is a factor of whether this
optimization were applied in a particular instance, or not).

The constructor-based member initialization will bury the
initializations to wherever the constructor is implemented,
which [typically] will not be visible to the compilation unit
that uses the class, hence the only way to communicate the
value of the initializer to the users of the class is to expend
a data item for it. Furthermore, the compiler would have
to scan multiple constructors to find out if the initialization
is indeed identical in all of them (a requirement for this
optimization to work).

In summary, allowing class-based reference initialization (as
opposed to the existing instance-based) would provide the
compiler with an opportunity to optimize away the storage
required by the initializer value, whenever its value can be
deterministically [re]calculated in compile-time without side
effects.

Cheers!

- Risto -

Jul 19 '05 #15

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

Similar topics

6
by: Steve | last post by:
Hi, I'm trying to convert a file reading loop into one using streams. The BSD OS read API returns the number of bytes read, but istream::read returns itself. How can I find out the number of...
0
by: munif | last post by:
i wnat write a C++ program that would read from a CD and display information about files and folders in the given CD In simple words you would be performing a simple (ls -l) or (DIR /S) on the...
12
by: Steven T. Hatton | last post by:
I know of a least one person who believes std::ifstream::read() and std::ofstream::write() are "mistakes". They seem to do the job I want done. What's wrong with them. This is the code I...
2
by: Sandman | last post by:
Just looking for suggestion on how to do this in my Web application. The goal is to keep track of what a user has and hasn't read and present him or her with new material I am currently doing...
4
by: Andreas Müller | last post by:
Hi, I'm working on a Linux-programm with a signal-handler and therfore I need to use the read-system-call instead of cin.get or sth. like that. With getline my program works fine, it reads a...
2
by: Andrea Bauer | last post by:
Hallo, wie kann ich so eine Datei unter .Net schreiben C++ oder C#. Bitte mit Funktionsaufrufen. Vielen Dank. Grüße Andrea <Product> <ProgramNumber>2</ProgramNumber>
9
by: ferbar | last post by:
Hi all, I'm trying to read from the txt file 'ip.packets.2.txt' using the read function. It seems everything ok, but I get a -1 when executing >>bytesr = read(fdo1, bufread, 2); The 'open'...
8
by: S Shulman | last post by:
Hi All I need to read a file to an array of bytes (any type of file) I tried using FileStream and BinaryReader but it doesn't seem to work Thank you, Shmuel
3
by: Ole | last post by:
I got a problem with serial port read which I use like this: sp.Read (byteBuffer, 0, 100); but the problem is that it returns before it has read the 100 bytes - is there a way to set up the...
1
by: Arpan | last post by:
The contents of a text file are as follows: The Quick Brown Fox Jumped Over The Lazy Dog. Note that there isn't any space at the end of each of the 3 lines. Now when I do this:
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
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...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
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: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
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...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
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)...

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.