473,785 Members | 3,417 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(M yData(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_ba ck(a); }
private:
deque<MyDatasto rage;
}
// (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*st orage;
}

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

(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**s torage;
}

May 3 '07 #1
9 1567
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<MyDa tastorage; // an object
public:
void Enque(MyData const& d)
{ storage.push_ba ck(d); } // storing a copy
};

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

(3)
class Example {
std::deque<MyDa ta**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<MyDa ta*storage; // an object
public:
void Enque(MyData* pd)
{ storage.push_ba ck(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...@com Acast.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<MyDa tastorage; // an object
public:
void Enque(MyData const& d)
{ storage.push_ba ck(d); } // storing a copy

};

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

};

(3)
class Example {
std::deque<MyDa ta**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<MyDa ta*storage; // an object
public:
void Enque(MyData* pd)
{ storage.push_ba ck(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...@com Acast.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<MyDa tastorage; // an object
public:
void Enque(MyData const& d)
{ storage.push_ba ck(d); } // storing a copy
};
(2)
class Example {
std::deque<MyDa ta*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d) ; } // storing a copy
};
(3)
class Example {
std::deque<MyDa ta**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<MyDa ta*storage; // an object
public:
void Enque(MyData* pd)
{ storage.push_ba ck(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...@com Acast.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<MyDa tastorage; // an object
public:
void Enque(MyData const& d)
{ storage.push_ba ck(d); } // storing a copy
};
(2)
class Example {
std::deque<MyDa ta*storage; // a pointer
public:
void Enque(MyData const& d)
{ storage->push_back(d) ; } // storing a copy
};
(3)
class Example {
std::deque<MyDa ta**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<MyDa ta*storage; // an object
public:
void Enque(MyData* pd)
{ storage.push_ba ck(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_ba ck(a); }
private:
deque<MyDatasto rage;
}
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*st orage;
}
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**s torage;
}
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 objektorientier ter Datenverarbeitu ng
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<MyDa ta*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<i nt>::iterator begin,
deque<int>::ite rator end)
: storage(begin, end) {}
private:
deque<intstorag e;
};

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<MyDa ta*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<i nt>::iterator begin,
deque<int>::ite rator end)
: storage(begin, end) {}
private:
deque<intstorag e;
};

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...@aepnetw orks.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<MyDa ta*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
6782
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 declared by the following lines: struct S { int i; const char c; }
2
2857
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 allocated on the stack since it's a value type variable - variable d is allocated on the stack since it's a value type variable Where does variable "c" get allocated? It's a value type, but not foundwithin a method.
4
3353
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, but what is a pile? Is it just another name for stack? Doing some reading, I found that value types use stack memory since the size can be determined at compile time and there's less overhead with this type of memory. So, I'm thinking this is...
9
3385
by: shine | last post by:
what is the difference between a heap and a stack?
14
2514
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 types in objects. But if they are objects why it´s need this conversion? Aren´t objects (basic types) like Java?
4
6198
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 considered as reference type.... My guess is the struct A is actually a valuetype with a string reference/address. So it acts as if struct A { int ptrStr; } Anyway, the ptrStr is like a
0
1105
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 allocated on stack and also its member variales on the stack. right?) whereas the class and its members are allocated on the heap. right? Now my question is this. Do the structure in c++ behave in the same manner as in c#. i.e structures are stored on...
1
2012
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
3993
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 built-in-like behavior for objects of class type. That leads to the "necessity" for the exception machinery so that errors from constructors can be handled. Is all that complexity worth it just to get built-in-like behavior from class objects? Maybe a...
0
9643
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
9480
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
10315
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...
0
8968
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
7494
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
6737
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5511
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4045
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
3
2877
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.