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

two types of heap allocated objects--any benefit?

Let's see two different usage of an STL container. I see (2) more
often when reading code over (1), dose that give any benefit or it's
purely a coding preference?

Also, please see the (3), I see (3) often in ppl' code, does that give
any benefit over (2)

Thanks for answering in advance:)

-------------------------------
class MyData;
class Example;

int main() {
Example example;
for(int i = 0 ; i < HUGE_NUM; i++) {
example.Enque(MyData(i));
}
}

class MyData {
public:
MyData(int i) {data = i; }
int data;
}

// (1) The first Example definition:
class Example {
public:
Example() {};
~Example() {};
Enque(MyData a) { storage.push_back(a); }
private:
deque<MyDatastorage;
}
// (2) We can define Example alternatively, like the following
class Example {
public:
Example() { storage = new deque<MyData>; }
~Example() { delete storage; };
Enque(int a) { storage->push_back(a); }
private:
deque<MyData*storage;
}

------------------------------
------------------------------

(3) The third approach doing similar thing.
class MyData;
class Example;
int main() {
Example example;
for(int i = 0 ; i < HUGE_NUM; i++) {
MyData* a = new MyData(i);
example.Enque(a);
}
}

class MyData {
public:
MyData(int i) {data = i; }
int data;
}

class Example {
public:
Example() { storage = new deque<MyData>; }
~Example() {
while (!storage->empty()) {
MyData* a = storage->pop_front();
delete a;
}
delete storage;
}
Enque(MyData *a) { storage->push_back(a); }
private:
deque<MyData**storage;
}

May 3 '07 #1
9 1545
newbie wrote:
Let's see two different usage of an STL container. I see (2) more
often when reading code over (1), dose that give any benefit or it's
purely a coding preference?

Also, please see the (3), I see (3) often in ppl' code, does that give
any benefit over (2)

Thanks for answering in advance:)
OK, let's rewrite this a tiny bit...

class MyData { ... }; // common to every case

(1)
class Example {
std::deque<MyDatastorage; // an object
public:
void Enque(MyData const& d)
{ storage.push_back(d); } // storing a copy
};

(2)
class Example {
std::deque<MyData*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d); } // storing a copy
};

(3)
class Example {
std::deque<MyData**storage; // a pointer
public:
void Enque(MyData* pd)
{ storage->push_back(pd); } // storing a pointer
};

Every case has its use. (1) is common and easy to understand
and maintain. Extra copies are made of 'MyData', and it's not
use polymorphically. (2) Is not really different from (1),
except that the member 'storage' is dynamically allocated.
Makes no difference, really. Is harder to maintain than (1).
(3) Stores pointers to MyData. That's a totally different
container since it allows polymorphic use of the objects stored
in 'storage'. The fact that 'storage' is a pointer makes no
difference (and no sense either, like in case 2). If you intend
to store and to use 'MyData' polymorphically, it's better to
have a combination of (1) and (3):

class Example {
std::deque<MyData*storage; // an object
public:
void Enque(MyData* pd)
{ storage.push_back(pd); } // storing a pointer
};

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 3 '07 #2
On May 2, 6:05 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
newbie wrote:
Let's see two different usage of an STL container. I see (2) more
often when reading code over (1), dose that give any benefit or it's
purely a coding preference?
Also, please see the (3), I see (3) often in ppl' code, does that give
any benefit over (2)
Thanks for answering in advance:)

OK, let's rewrite this a tiny bit...

class MyData { ... }; // common to every case

(1)
class Example {
std::deque<MyDatastorage; // an object
public:
void Enque(MyData const& d)
{ storage.push_back(d); } // storing a copy

};

(2)
class Example {
std::deque<MyData*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d); } // storing a copy

};

(3)
class Example {
std::deque<MyData**storage; // a pointer
public:
void Enque(MyData* pd)
{ storage->push_back(pd); } // storing a pointer

};

Every case has its use. (1) is common and easy to understand
and maintain. Extra copies are made of 'MyData', and it's not
use polymorphically. (2) Is not really different from (1),
except that the member 'storage' is dynamically allocated.
Makes no difference, really. Is harder to maintain than (1).
(3) Stores pointers to MyData. That's a totally different
container since it allows polymorphic use of the objects stored
in 'storage'. The fact that 'storage' is a pointer makes no
difference (and no sense either, like in case 2). If you intend
to store and to use 'MyData' polymorphically, it's better to
have a combination of (1) and (3):

class Example {
std::deque<MyData*storage; // an object
public:
void Enque(MyData* pd)
{ storage.push_back(pd); } // storing a pointer

};

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Thanks a lot. Very helpful.

May 3 '07 #3
On May 2, 9:50 pm, newbie <mitbb...@yahoo.comwrote:
On May 2, 6:05 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
newbie wrote:
Let's see two different usage of an STL container. I see (2) more
often when reading code over (1), dose that give any benefit or it's
purely a coding preference?
Also, please see the (3), I see (3) often in ppl' code, does that give
any benefit over (2)
Thanks for answering in advance:)
OK, let's rewrite this a tiny bit...
class MyData { ... }; // common to every case
(1)
class Example {
std::deque<MyDatastorage; // an object
public:
void Enque(MyData const& d)
{ storage.push_back(d); } // storing a copy
};
(2)
class Example {
std::deque<MyData*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d); } // storing a copy
};
(3)
class Example {
std::deque<MyData**storage; // a pointer
public:
void Enque(MyData* pd)
{ storage->push_back(pd); } // storing a pointer
};
Every case has its use. (1) is common and easy to understand
and maintain. Extra copies are made of 'MyData', and it's not
use polymorphically. (2) Is not really different from (1),
except that the member 'storage' is dynamically allocated.
Makes no difference, really. Is harder to maintain than (1).
(3) Stores pointers to MyData. That's a totally different
container since it allows polymorphic use of the objects stored
in 'storage'. The fact that 'storage' is a pointer makes no
difference (and no sense either, like in case 2). If you intend
to store and to use 'MyData' polymorphically, it's better to
have a combination of (1) and (3):
class Example {
std::deque<MyData*storage; // an object
public:
void Enque(MyData* pd)
{ storage.push_back(pd); } // storing a pointer
};
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Thanks a lot. Very helpful.
There is a case where you would want to keep your member data as
pointers, that's when you don't want to call the default constructor
on them, hence you create them manually.

For example, the stl containers takes iterator inputs as constructor
parameter, if you want to call those constructors, keep them as
pointers.

regards,

PQ

May 3 '07 #4
On 3 Maj, 07:47, pmouse <pmo...@cogeco.cawrote:
On May 2, 9:50 pm, newbie <mitbb...@yahoo.comwrote:
On May 2, 6:05 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
newbie wrote:
Let's see two different usage of an STL container. I see (2) more
often when reading code over (1), dose that give any benefit or it's
purely a coding preference?
Also, please see the (3), I see (3) often in ppl' code, does that give
any benefit over (2)
Thanks for answering in advance:)
OK, let's rewrite this a tiny bit...
class MyData { ... }; // common to every case
(1)
class Example {
std::deque<MyDatastorage; // an object
public:
void Enque(MyData const& d)
{ storage.push_back(d); } // storing a copy
};
(2)
class Example {
std::deque<MyData*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d); } // storing a copy
};
(3)
class Example {
std::deque<MyData**storage; // a pointer
public:
void Enque(MyData* pd)
{ storage->push_back(pd); } // storing a pointer
};
Every case has its use. (1) is common and easy to understand
and maintain. Extra copies are made of 'MyData', and it's not
use polymorphically. (2) Is not really different from (1),
except that the member 'storage' is dynamically allocated.
Makes no difference, really. Is harder to maintain than (1).
(3) Stores pointers to MyData. That's a totally different
container since it allows polymorphic use of the objects stored
in 'storage'. The fact that 'storage' is a pointer makes no
difference (and no sense either, like in case 2). If you intend
to store and to use 'MyData' polymorphically, it's better to
have a combination of (1) and (3):
class Example {
std::deque<MyData*storage; // an object
public:
void Enque(MyData* pd)
{ storage.push_back(pd); } // storing a pointer
};
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Thanks a lot. Very helpful.

There is a case where you would want to keep your member data as
pointers, that's when you don't want to call the default constructor
on them, hence you create them manually.

For example, the stl containers takes iterator inputs as constructor
parameter, if you want to call those constructors, keep them as
pointers.
Another case when you want to store pointers to the data instead of
copies are when you want to have to same object in multiple containers
(or rather pointers to the same data). Something like:

Example ex1;
Example ex2;
for (int i = 0; i < HUGE; ++i) {
MyData* a = new MyData();
ex1.Enque(a);
ex2.Enque(a);
}

Than any changes made to objects in ex1 will also be made to those in
ex2, which would not be the case if you used methods 1 or 2.

--
Erik Wikström

May 3 '07 #5
newbie wrote:
Let's see two different usage of an STL container. I see (2) more
often when reading code over (1), dose that give any benefit or it's
purely a coding preference?
Also, please see the (3), I see (3) often in ppl' code, does that give
any benefit over (2)
Thanks for answering in advance:)
[...]
// (1) The first Example definition:
class Example {
public:
Example() {};
~Example() {};
Enque(MyData a) { storage.push_back(a); }
private:
deque<MyDatastorage;
}
This is more or less that standard way of doing things in C++.
// (2) We can define Example alternatively, like the following
class Example {
public:
Example() { storage = new deque<MyData>; }
~Example() { delete storage; };
Enque(int a) { storage->push_back(a); }
private:
deque<MyData*storage;
}
And I've never seen this. What's the point? (In my experience,
pointers to standard containers are very, very rare. The only
occur when several objects share the same container.)
(3) The third approach doing similar thing.
class MyData;
class Example;
int main() {
Example example;
for(int i = 0 ; i < HUGE_NUM; i++) {
MyData* a = new MyData(i);
example.Enque(a);
}
}
class MyData {
public:
MyData(int i) {data = i; }
int data;
}
class Example {
public:
Example() { storage = new deque<MyData>; }
~Example() {
while (!storage->empty()) {
MyData* a = storage->pop_front();
delete a;
}
delete storage;
}
Enque(MyData *a) { storage->push_back(a); }
private:
deque<MyData**storage;
}
Again, fairly rare. As I mentioned above, it would be very rare
to have a pointer to a container. It's not particularly rare,
however, for containers to contain pointers, and while not
usually the case, it sometimes happens that they own the
pointers as well, and are responsible for deleting them. (This
most often happens when the contained object has identity, and
is not copiable.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 3 '07 #6
On 3 May, 06:47, pmouse <pmo...@cogeco.cawrote:
On May 2, 9:50 pm, newbie <mitbb...@yahoo.comwrote:
(2)
class Example {
std::deque<MyData*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d); } // storing a copy
};
There is a case where you would want to keep your member data as
pointers, that's when you don't want to call the default constructor
on them, hence you create them manually.

For example, the stl containers takes iterator inputs as constructor
parameter, if you want to call those constructors, keep them as
pointers.
Are you suggesting a case where the OP's example 2 might be useful?
Because if so, I don't see what your getting at. I can have a
std::deque member and initialise it in any way I want.

#include <deque>
using namespace std;

class Example
{
public:
Example(deque<int>::iterator begin,
deque<int>::iterator end)
: storage(begin, end) {}
private:
deque<intstorage;
};

int main()
{
deque<intd;
d.push_back(42);
Example e(d.begin(), d.end());
}

Gavin Deane

May 3 '07 #7
>
Another case when you want to store pointers to the data instead of
copies are when you want to have to same object in multiple containers
(or rather pointers to the same data). Something like:

Example ex1;
Example ex2;
for (int i = 0; i < HUGE; ++i) {
MyData* a = new MyData();
ex1.Enque(a);
ex2.Enque(a);
}

Than any changes made to objects in ex1 will also be made to those in
ex2, which would not be the case if you used methods 1 or 2.

--
Erik Wikström
This often hints at a logical flaw in software design. I would verify
carefully that this is something warranted. This causes a lot of trouble
in multi-threaded programs.
May 3 '07 #8
Gavin Deane wrote:
On 3 May, 06:47, pmouse <pmo...@cogeco.cawrote:
>On May 2, 9:50 pm, newbie <mitbb...@yahoo.comwrote:
>>>(2)
class Example {
std::deque<MyData*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d); } // storing a copy
};
There is a case where you would want to keep your member data as
pointers, that's when you don't want to call the default constructor
on them, hence you create them manually.

For example, the stl containers takes iterator inputs as constructor
parameter, if you want to call those constructors, keep them as
pointers.

Are you suggesting a case where the OP's example 2 might be useful?
Because if so, I don't see what your getting at. I can have a
std::deque member and initialise it in any way I want.

#include <deque>
using namespace std;

class Example
{
public:
Example(deque<int>::iterator begin,
deque<int>::iterator end)
: storage(begin, end) {}
private:
deque<intstorage;
};

int main()
{
deque<intd;
d.push_back(42);
Example e(d.begin(), d.end());
}

Gavin Deane
He's talking about case (3).
May 3 '07 #9
On 3 May, 15:32, Fei Liu <fei...@aepnetworks.comwrote:
Gavin Deane wrote:
On 3 May, 06:47, pmouse <pmo...@cogeco.cawrote:
On May 2, 9:50 pm, newbie <mitbb...@yahoo.comwrote:
(2)
class Example {
std::deque<MyData*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d); } // storing a copy
};
There is a case where you would want to keep your member data as
pointers, that's when you don't want to call the default constructor
on them, hence you create them manually.
For example, the stl containers takes iterator inputs as constructor
parameter, if you want to call those constructors, keep them as
pointers.
Are you suggesting a case where the OP's example 2 might be useful?
Because if so, I don't see what your getting at. I can have a
std::deque member and initialise it in any way I want.
<snip>
He's talking about case (3).
You sure? The OP's case 3 had a member pointer-to-deque, just like
case 2, but the deque stored pointers rather than objects. I can see
why sometimes you might want a container of objects and other times a
container of pointers. But I was responding to a comment about "member
data as pointers" (so far in this thread, the member data is the
container itself) and not wanting to use the default constructor for
the container. Whether the container happens to store pointers or
objects doesn't seem to me to be relevant to the comment from pmouse
that I quoted. And if the difference between the container holding
pointers or objects is irrelevant, the OP's cases 2 and 3 are
identical - in both cases class Example holds a pointer-to-deque and
my comments apply equally to cases 2 and 3.

pmouse's comment looked to me like a reason for preferring the type of
the member in class Example to be pointer-to-deque rather than deque.
It didn't look to me like pmouse was suggesting a reason for
preferring to store pointers rather than objects in the deque.

I can't immediately see any reason for class Example to hold a pointer-
to-deque rather than a deque, whether the container holds objects or
pointers.

Gavin Deane

May 3 '07 #10

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

Similar topics

4
by: Wolfgang Jeltsch | last post by:
Hello, I can initialized, e.g, heap-allocated ints by writing something like new int(5). Now I'd like to know if it is possible to do the same thing for struct types. Say, I have a struct...
2
by: Nick McCamy | last post by:
I have a question related to allocating on the stack. In this program below, are my following assumptions true? - variable a is allocated on the heap since it's static - variable b is...
4
by: Robbie | last post by:
Someone at work asked me this question: Value types--do they hit the heap or the pile? Well, I was a bit dumbfounded, because I never heard of the term "pile". I've heard of heap and stack,...
9
by: shine | last post by:
what is the difference between a heap and a stack?
14
by: luis | last post by:
Are basic types (int, long, ...) objetcs or not? I read that in C# all are objects including basic types, derived from Object class. Then in msdn documentation says that boxing converts basic...
4
by: haitao.song | last post by:
Hi, As it is always stated that value type is allocated on stack, while reference types are on managed heap. How about the struct with string members? stuct A { string str; } String type is...
0
by: nayannovellus | last post by:
As i know that in c# types are categorized into 2, namely :- Value types(int,char,double...etc and also struct) and Reference types(class,enum...etc). Value types are allocated on stack(struct is...
1
by: Martin | last post by:
Hi. I've found a few topics on this subject, but still not sure and decided to post mine. Here's my example: #include <iostream> using namespace std;
55
by: tonytech08 | last post by:
How valuable is it that class objects behave like built-in types? I appears that the whole "constructor doesn't return a value because they are called by the compiler" thing is to enable...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
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...
0
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,...

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.