473,326 Members | 2,815 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,326 software developers and data experts.

Encapsulation idiom

Hi,

This is a design question. I have a class named "DataBuffer" that
stores some data. After "DataBuffer" is created it can not be modified.
All the methods of "DataBuffer" are const as data can not be modified
after it was created.

Up to here everything is fine. The problem is when I want to get clever
with data storage. My program has an array of "DataBuffers" that gets
pre-allocated. If I want to use that memory instead of creating a new
"DataBuffer" each time, I get a pointer to the internal data with a
method and then I use that to fill the data directly. The problem with
this is that it breaks encapsulation as everybody has now access to the
internal data.

Alternatively, I can still use the constructor option, create a new
instance of "DataBuffer" on the stack (or previsouly allocated) with
the new data and then do a copy (operator=) to the data previously
allocated. This works and doesn't break encapsulation but is rather
inefficient as it uses two copies of the data.

I though on declaring the method of the class that stores the data a
"friend" of "DataBuffer". Unfortunately, I use inheritance and a
virtual method so "friend" does not work.

Does anybody knows of a way to do this without braking encapsulation
and without paying an efficiency penalty?

Thanks

Feb 3 '06 #1
5 1645
TB
jm*******@gmail.com sade:
Hi,

This is a design question. I have a class named "DataBuffer" that
stores some data. After "DataBuffer" is created it can not be modified.
All the methods of "DataBuffer" are const as data can not be modified
after it was created.

Up to here everything is fine. The problem is when I want to get clever
with data storage. My program has an array of "DataBuffers" that gets
pre-allocated. If I want to use that memory instead of creating a new
"DataBuffer" each time, I get a pointer to the internal data with a
method and then I use that to fill the data directly. The problem with
this is that it breaks encapsulation as everybody has now access to the
internal data.

Alternatively, I can still use the constructor option, create a new
instance of "DataBuffer" on the stack (or previsouly allocated) with
the new data and then do a copy (operator=) to the data previously
allocated. This works and doesn't break encapsulation but is rather
inefficient as it uses two copies of the data.

I though on declaring the method of the class that stores the data a
"friend" of "DataBuffer". Unfortunately, I use inheritance and a
virtual method so "friend" does not work.

Does anybody knows of a way to do this without braking encapsulation
and without paying an efficiency penalty?

Thanks


Provide an iterator instead of a raw pointer.

--
TB @ SWEDEN
Feb 3 '06 #2
jm*******@gmail.com wrote:
This is a design question. I have a class named "DataBuffer" that
stores some data. After "DataBuffer" is created it can not be modified.
All the methods of "DataBuffer" are const as data can not be modified
after it was created.

Up to here everything is fine. The problem is when I want to get clever
with data storage. My program has an array of "DataBuffers" that gets
pre-allocated. If I want to use that memory instead of creating a new
"DataBuffer" each time, I get a pointer to the internal data with a
method and then I use that to fill the data directly. The problem with
this is that it breaks encapsulation as everybody has now access to the
internal data.
Uh... Why do you need to "get a pointer to the internal data"? Can't you
simply use 'placement new' and _construct_ the object? Of course, you
have to remember to destroy the element once it's not needed any longer.

I would recommend to have a _factory_ for your objects that would do what
you describe. It will _own_ the array of elements and give out the stored
objects by pointer by creating another one in place. This is "pooling",
you have a "pool" of elements (or placeholders) and reuse them. Of course
the pool has to be inaccessible for anybody else but the factory.
[...]


V
Feb 3 '06 #3
* jm*******@gmail.com:

This is a design question. I have a class named "DataBuffer" that
stores some data. After "DataBuffer" is created it can not be modified.
All the methods of "DataBuffer" are const as data can not be modified
after it was created.
Good so far, you have logically const DataBuffer obejcts.

Up to here everything is fine. The problem is when I want to get clever
with data storage.
Ah, there's the rub, yes.

General advice is, _don't_ be "clever".

But since you probably have good reasons (unstated), I'll address that
question.

My program has an array of "DataBuffers" that gets pre-allocated.
A pool.

If I want to use that memory instead of creating a new
"DataBuffer" each time, I get a pointer to the internal data with a
method and then I use that to fill the data directly. The problem with
this is that it breaks encapsulation as everybody has now access to the
internal data.
Yes, that's a problem.

It's simple.

Have a pool of storage instead of a pool of DataBuffer objects.

When constructing a DataBuffer object, obtain a pointer to storage from
the pool, and pass that to the DataBuffer constructor.

When destroying a DataBuffer object, return its data storage to the
pool.

Alternatively, I can still use the constructor option, create a new
instance of "DataBuffer" on the stack (or previsouly allocated) with
the new data and then do a copy (operator=) to the data previously
allocated. This works and doesn't break encapsulation
(1) It doesn't work because (2) it does break encapsulation (and it's
inconsistent with your earlier claim that all 'methods' are const).

If DataBuffer objects are meant to be logically const, remove access to
copy assignment.

but is rather
inefficient as it uses two copies of the data.
And yes, (3), it's inefficient in addition to being unsafe.

I though on declaring the method of the class that stores the data a
"friend" of "DataBuffer". Unfortunately, I use inheritance and a
virtual method so "friend" does not work.
To me neither of these two statements are meaningful, sorry.

Does anybody knows of a way to do this without braking encapsulation
and without paying an efficiency penalty?


See above.

Hth.,

- Alf

--
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?
Feb 3 '06 #4
Regarding TB's answer, I'll prefer not to have access at all so I
consider an iterator almost the same as direct memory access.

On Victor's answer, the problem that I have with "placement new" is
that "DataBuffer" is a storage class that also has containers. Actually
one of the members is a Qt's QVector. Basically I think I can't pre
allocate a memory pool and then use it as the storage for the array of
DataBuffers.

My other thought (on the factory line) is this. What if the interface
class (the base of the class that actually does the job of reading the
data and store it in a DataBuffer by a virtual method) has a non
inherited method (factory method) that is a "friend" of "DataBuffer"
and then calls the "virtual storage method" that used to have a
DataBuffer* as a parameter but now pass the internal pointer? I can do
that now that the factory is a "friend" method. I'm not sure if this is
too ugly but it doesn't seem to violate encapsulation and nobody
besides the factory method can change the data.

Feb 3 '06 #5
jm*******@gmail.com wrote:
Regarding TB's answer, I'll prefer not to have access at all so I
consider an iterator almost the same as direct memory access.

On Victor's answer, the problem that I have with "placement new" is
that "DataBuffer" is a storage class that also has containers.
Actually one of the members is a Qt's QVector. Basically I think I
can't pre allocate a memory pool and then use it as the storage for
the array of DataBuffers.
This is a common misconception about the size of object that
themselves have some dynamic memory allocation. I don't want to
get into it, twice a week is one time too many. If you can't
preallocate memory, don't.
My other thought (on the factory line) is this. What if the interface
class (the base of the class that actually does the job of reading the
data and store it in a DataBuffer by a virtual method) has a non
inherited method (factory method) that is a "friend" of "DataBuffer"
and then calls the "virtual storage method" that used to have a
DataBuffer* as a parameter but now pass the internal pointer?
So? Do you have a suspicion of something bad? If yes, state it.
If not, guessing game belongs to Vegas.
I can do
that now that the factory is a "friend" method. I'm not sure if this
is too ugly but it doesn't seem to violate encapsulation and nobody
besides the factory method can change the data.


If you can do it now, do it. If it does what you need, why don't
you use it already?

V
--
Please remove capital As from my address when replying by mail
Feb 4 '06 #6

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

Similar topics

2
by: .pd. | last post by:
If I have a control that adds itself to its container, does that break encapsulation? Is it a bad thing? Here's what I mean: public class fred { public barny b; public fred() {
3
by: K.K. | last post by:
Consider the following code: >>>>>>>>>>> // Define an empty class public class ZorgleCollection : Dictionary<string, Zorgle> { } // Somewhere outside ZorgleCollection:
3
by: enchantingdb | last post by:
I have an exam tomorrow that covers the perceived advantages and disadvantages of object oriented programming, in particular polymorphism, inheritance and encapsulation. I know the advantages but...
6
by: William H. Burling | last post by:
I am not sure I understand encapsulation. I thought that one of the objectives in OOPs is to hide data structures from other objects so that they did not have to know how to unpack them. ...
13
by: Steven D'Aprano | last post by:
I was playing around with simple memoization and came up with something like this: _cache = {} def func(x): global _cache if _cache.has_key(x): return _cache else: result = x+1 # or a time...
47
by: Roger Lakner | last post by:
I often see operator implemented something like this: class Foo { ... }; class FooList { public: const Foo& operator (unsigned index) const {return array;}; Foo& operator (unsigned index) ...
32
by: bluejack | last post by:
Ahoy: For as long as I've been using C, I've vacillated on the optimal degree of encapsulation in my designs. At a minimum, I aggregate data and code that operate on that data into classlike...
16
by: copx | last post by:
I have recently read "Everything you ever wanted to know about C types" by Peter Seebach (1), and learned about incomplete types. Now, I realise the value of encapsulation, but I wonder whether it...
2
by: subramanian100in | last post by:
Is my following understanding correct ? Data abstraction means providing the interface - that is, the set of functions that can be called by the user of a class. Information hiding means...
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
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...
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: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.