473,659 Members | 3,631 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

accessors


i have a question about class design, specifically regarding accessor
functions. which is probably a better design?

class foo
{
public:
void name(string const& n) { name_ = n; }
string name() const { return name_; }
private:
string name_;
};

class foo
{
public:
string& name() { return name_; }
string name() const { return name_; }
private:
string name_;
};

the difference from the client point of view is how you set the name:

foo f;
f.name("name");
// or
f.name() = "name";

the way i figure it, the first would make assignments explicit, and
prevent accidental assignments. however, when you consider *reading* the
name, you get a different story. there's no difference for simple types
(with fast copying/copy construction), but for expensive types you pay
for a copy construction (or at least something to that effect) using the
first option, even if you don't need it. with the second you only pay
for it on const objects (and i'll get to that next).

now, for integral types, it's not a cost issue, so there it's just a
style issue. but for code passing bigger things around, there is no
point paying for unnecessary copying if it can be avoided. given that
constraint, this would seem like the best option:

class foo
{
public:
string& name() { return name_; }
string const& name() const { return name_; }
private:
string name_;
};

are there any thoughts on this?

mark
Jul 22 '05 #1
12 1771
* Mark A. Gibbs:

i have a question about class design, specifically regarding accessor
functions. which is probably a better design?

class foo
{
public:
void name(string const& n) { name_ = n; }
string name() const { return name_; }
private:
string name_;
};

class foo
{
public:
string& name() { return name_; }
string name() const { return name_; }
private:
string name_;
};

the difference from the client point of view is how you set the name:

foo f;
f.name("name");
// or
f.name() = "name";
Both ugly.

the way i figure it, the first would make assignments explicit
It doesn't.

and prevent accidental assignments.
It doesn't.

however, when you consider *reading* the
name, you get a different story. there's no difference for simple types
(with fast copying/copy construction), but for expensive types you pay
for a copy construction (or at least something to that effect) using the
first option, even if you don't need it. with the second you only pay
for it on const objects (and i'll get to that next).
Before optimizing for speed and memory, measure.

Before measuring, check whether there really is a problem.

Before checking for that, use sound judgement in coding, such as
returning a member data item by reference to const.

are there any thoughts on this?


'set_what' or 'setWhat' are good names for setting a 'what': use the
imperative form when naming an action to be performed, use a
description when naming a data item.

Return of reference to const object is a good but limited way to avoid
excessive copying.

A function that returns a reference to a member is equivalent to
exposing that member directly and is in general Ungood (TM).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #2

"Mark A. Gibbs" <x_*********@ro gers.com_x> wrote in message news:rF******** **************@ twister01.bloor .is.net.cable.r ogers.com...

i have a question about class design, specifically regarding accessor
functions. which is probably a better design?


Actually, I'd do:

const string& name() const { return name; }

This avoids the copy, and keeps people who grab the reference
without copying it to not change the underlying object.

Jul 22 '05 #3
"Mark A. Gibbs" <x_*********@ro gers.com_x> wrote:
i have a question about class design, specifically regarding accessor
functions. which is probably a better design?

class foo
{
public:
void name(string const& n) { name_ = n; }
string name() const { return name_; }
private:
string name_;
};

class foo
{
public:
string& name() { return name_; }
string name() const { return name_; }
private:
string name_;
};
class RemoteFoo {
Socket commSocket; // sends and receives data to/from another computer
public:
// wich public interface works here?
void name( string const& n );
// works well we send 'n' to the other computer
string name() const;
// works well we request name from the other computer and return it
string& name();
// no good, we are forced to maintain data on this computer
};

class DatabaseFoo {
DB db; // stores data in a database
public:
// wich public interface works here?
void name( string const& n );
// works well we send 'n' to the Database
string name() const;
// works well we request name from the Database and return it
string& name();
// no good, we are forced to maintain data in RAM
};

My point here is that "string& foo::name()" forces us into a spicific
implementation and that is a Bad Thing.

the difference from the client point of view is how you set the name:

foo f;
f.name("name");
// or
f.name() = "name";
The difference from the client point of view is neglidgable, the
difference from the server point of view is great.
are there any thoughts on this?


IMO your best bet is to start with:

class foo {
string name_;
public:
const string name() const { return name_; }
void name( const string& n ) {
name_ = n;
}
};

Then if profiling shows that calling "name() const" is too expensive,
change it to "const string& foo::name() const" wich will not affect
existing clients in any way.
Jul 22 '05 #4
>> foo f;
f.name("name");
// or
f.name() = "name";


Another possible argument in favor of f.name("name") would be that the function
could perform a sanity check on its argument if necessary.

As another poster pointed out simply returning a reference to a data member,
even one that is part of the visible state of the object, is probably just as
bad as having that data member be public.
Jul 22 '05 #5
Mark A. Gibbs wrote:

i have a question about class design, specifically regarding accessor
functions. which is probably a better design?

class foo
{
public:
void name(string const& n) { name_ = n; }
string name() const { return name_; }
private:
string name_;
};

class foo
{
public:
string& name() { return name_; }
string name() const { return name_; }
private:
string name_;
}; [snip]

are there any thoughts on this?

mark


I would choose to return a _copy_ of the string, not
a reference to the string. A copy allows the string
to be stored elsewhere or computed on-the-fly. Passing
by reference means that the string variable must always
exist.

This has bitten me on several occasions. :-(

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.l earn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 22 '05 #6
On Wed, 18 Aug 2004 14:28:53 GMT, Thomas Matthews
<Th************ *************** *@sbcglobal.net > wrote:

[snip]
I would choose to return a _copy_ of the string, not
a reference to the string. A copy allows the string
to be stored elsewhere or computed on-the-fly.
Well, only if you are paranoid about clients grabbing the address of
the string and doing unmentionable things to it (even if it is a const
&) ...
Passing by reference means that the string variable must always
exist.
How could the variable "not exist" if you have a string member? It
might be empty, but it does exist. I can only see a problem if you
have a pointer to a string as member, or perhaps a char *, and try to
dereference it when it is null.
This has bitten me on several occasions. :-(


How?
--
Bob Hairgrove
No**********@Ho me.com
Jul 22 '05 #7

Bob Hairgrove wrote:
Passing by reference means that the string variable must always
exist.

How could the variable "not exist" if you have a string member? It
might be empty, but it does exist. I can only see a problem if you
have a pointer to a string as member, or perhaps a char *, and try to
dereference it when it is null.

This has bitten me on several occasions. :-(

How?


he has a good point actually - imagine i was making a class with a
colour member, and i chose to initially represent that colour as a long:

class foo
{
public:
void set_colour(long c) { c_ = c; }
long const& colour() const ( return c_; }

private:
long c_;
};

then later i changed it to use an existing colour class:

class foo
{
public:
void set_colour(long c) { c_.assign_long( c); c_as_long_ = c; }
long const& colour() const ( return c_as_long_; }

private:
colour_type c_;
long c_as_long_;
};

that's what i'd have to do to maintain the existing interface. on the
other hand, if i'd done:

class foo
{
public:
void set_colour(long c) { c_ = c; }
long colour() const { return c_; }
private:
long c_;
};

then to change c_ to a colour_type is trivial.

class foo
{
public:
void set_colour(long c) { c_.assign_long( c); }
long colour() const { return c_.to_long(); }
private:
colour_type c_;
};

mark

Jul 22 '05 #8

so to summarize several posts (thank you to all contributors), i
personally think the best choice for me would be:

class foo
{
public:
void set_name(string const& n) { n = name_; }
string const& name() const { return name_; }
private:
string name_;
};

daniel t. mentioned that returning references from functions makes using
the function in a distributed environment more difficult, and if the
value returned has to be read from an external source it would have to
have a copy maintained in ram. my response to the first concern is that
i, personally, never write code to be used across application
boundaries, but if i did, "string const& name() const" is functionally
the same as "string name() const", so i don't see why i'd have to change
anything (but if i did, the change does not really affect client code,
beyond making it more expensive). as for the second point, i was
referring specifically to member accessors, but if i were to deal with
the case mentioned, i would think maintaining a local copy of small
amounts of data would probably be "better" performance-wise than reading
it out of a hard disk on each call - but if it cost too much memory to
maintain the data, and/or the data should be read "fresh" on each call,
i would not disguise the call as a call to an accessor, i would use an
imperative function name (as mr. steinbach suggested) and return by
value, so the costs are clearly visible.

i think that in general i can assume a certain amount of trust with
client code. if someone really wants to do dumb things, there are plenty
of ways to do it in c++. in the same way that basic_string.c_ str() notes
that the memory pointed to in the return value belongs to the string and
1) should not be changed by the application or 2) may become invalid
after a modifying operation on the string, i think i can note to client
code that the object referenced in the return belongs to the class,
should not be messed around with by clients and may be invalid after a
modifying operation. there's no practical way you can "accidently " do
anything unkosher to a const reference. and maintaining references to
any object without a severely restricted scope is a risky thing to do.

mark

Jul 22 '05 #9
"Mark A. Gibbs" <x_*********@ro gers.com_x> wrote in message news:<rF******* *************** @twister01.bloo r.is.net.cable. rogers.com>...
[snip]
class foo
{
public:
string& name() { return name_; }
string name() const { return name_; }
private:
string name_;
};


Does that compile? The two name functions differ only in the
type of the returned object, one a string, the other a string &.
Socks
Jul 22 '05 #10

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

Similar topics

12
2007
by: Christopher J. Bottaro | last post by:
If I have the following class: class MyClass: def __init__(self): m_dict = {} m_dict = 1 m_dict = 2 m_dict = 3 Is there anyway to generate automatic accessors to the elements of the dict?
2
1731
by: cody | last post by:
Does the clr allow more than one set and one get method for a property? Is it possible to use overloading for example set_Color(int c), set_Color(Color c)? from msdn: PropertyInfo.GetAccessors Method () Return Value An array of MethodInfo objects that reflect the public get, set, *and other
10
5777
by: Zap | last post by:
Widespread opinion is that public data members are evil, because if you have to change the way the data is stored in your class you have to break the code accessing it, etc. After reading this (also copied below for easier reference): http://groups.google.it/groups?hl=en&lr=&safe=off&selm=6beiuk%24cje%40netlab.cs.rpi.edu&rnum=95 I don't agree anymore.
1
1476
by: Brad Williams | last post by:
When I try to define accessors for this event, the event invocation line stops compiling. What's wrong? public class TestClass { public delegate int MyDelegate(string s); public event MyDelegate myEvent { add { Console.WriteLine("myEvent.Add"); } remove { Console.WriteLine("myEvent.Remove"); }
3
2065
by: Peter Cresswell | last post by:
Hello everyone, I would like to serialize an object to XML. Currently my code will serialize all of the public properties that are value types, but not my public properties that have get accessors. e.g: public class MyObject { public string name; // This is serialized OK
0
1139
by: mrvernon | last post by:
Say an ASP.NET service has a class with accessors with corresponding private data, for instance: class Foo { private int bar; public int Bar { get { return bar; } set { value = bar; }
1
1579
by: Rafael Pivato | last post by:
There is something like C# Event Accessors at VB.NET ? ----- Rafael Pivato
112
13804
by: mystilleef | last post by:
Hello, What is the Pythonic way of implementing getters and setters. I've heard people say the use of accessors is not Pythonic. But why? And what is the alternative? I refrain from using them because they smell "Javaish." But now my code base is expanding and I'm beginning to appreciate the wisdom behind them. I welcome example code and illustrations.
0
8428
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
8337
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
8851
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...
1
8531
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7359
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...
1
6181
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
4175
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...
1
2754
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
2
1739
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.