473,772 Members | 3,603 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Container elements with const members

The requirement that STL container elements have to be assignable is causing
me a problem.
Consider a class X which contains both const and non-const data members:

class X
{
public:
X(const std::string &rStrId, int x) : m_strId(strId), m_x(x)
{
}

private:
X& operator=(const X &rhs); // not allowed
X(const X& rhs); // not allowed

const std::string m_strId;
int m_x;
};

I know that because I have the data member, m_strId, declared as *const*, it
means that I cannot assign to it. This was OK as I didn't need to and
therefore made it private with no implementation.

Then I decided that I needed to have an STL vector of Xs.

X x(std::string(" hello"), 43);
std::vector<X > xVector;
....
xVector.push_ba ck(X(std::strin g("hello"), 43));

I know too that when using STL containers the standard says that the
contained objects must be copyable and assignable.

This is my dilemma. If I don't supply an assignment operator for X or I make
it private then it won't compile when I try to push an instance of X into
the vector.

I have considered the following options:

1) Make the string non const and let the compiler generate the assignment
operator. I don't want to do this as each instance of X is required to have
a unique string identifier, m_strId, which will not change throughout the
lifetime of the object.

2) Provide an assignment operator that only assigns the non const int m_x.
This would allow the possibility of assigning one X object to another and
the result not being equal.

Which is the best option of the two? Are there any other alternatives I
haven't considered which are better?

TIA

RP
Jul 22 '05 #1
8 1768
"Nobody" <No****@Nobody. co.uk> wrote in message news:E4Bhc.3313
class X
{
public:
X(const std::string &rStrId, int x) : m_strId(strId), m_x(x)
{
}

private:
X& operator=(const X &rhs); // not allowed
X(const X& rhs); // not allowed

const std::string m_strId; I know too that when using STL containers the standard says that the
contained objects must be copyable and assignable. 1) Make the string non const and let the compiler generate the assignment
operator. I don't want to do this as each instance of X is required to have a unique string identifier, m_strId, which will not change throughout the
lifetime of the object.
Yes, your design should reflect your business requirements, not the
technical requirements on STL containers.
2) Provide an assignment operator that only assigns the non const int m_x.
This would allow the possibility of assigning one X object to another and
the result not being equal.
Yes, this also violates your business requirement.
Which is the best option of the two? Are there any other alternatives I
haven't considered which are better?


Use a container of pointers to X. Remember to delete the pointed to objects
when the container goes out of scope.

You could try smart pointers, like so:

std::vector<boo st::shared_ptr< X> > d_container;
Jul 22 '05 #2
On Wed, 21 Apr 2004, Nobody wrote:

[snip]
class X
{
public:
X(const std::string &rStrId, int x) : m_strId(strId), m_x(x)
{
}

private:
X& operator=(const X &rhs); // not allowed
X(const X& rhs); // not allowed

const std::string m_strId;
int m_x;
};
[snip]
X x(std::string(" hello"), 43);
std::vector< X > xVector;
...
xVector.push_ba ck(X(std::strin g("hello"), 43));

I know too that when using STL containers the standard says that the
contained objects must be copyable and assignable.
[snip]
I have considered the following options:

1) Make the string non const and let the compiler generate the assignment
operator. I don't want to do this as each instance of X is required to have
a unique string identifier, m_strId, which will not change throughout the
lifetime of the object.

2) Provide an assignment operator that only assigns the non const int m_x.
This would allow the possibility of assigning one X object to another and
the result not being equal.

Which is the best option of the two?
Neither option is correct if your code must guarantee that there is only
one instance for any string identifier, and the same string identifier
for a given object throughout the object's lifetime.
Are there any other alternatives I
haven't considered which are better?


Yes, store pointers in the vector. For example:

#include <vector>
#include <string>

class X
{
public:
X(const std::string &rStrId, int x)
: m_strId(rStrId) , m_x(x)
{}

private:
X& operator=(const X &rhs); //not allowed
X(const X& rhs); //not allowed

const std::string m_strId;
int m_x;
};

class App
{
std::vector<X*> m_pvx;

public:
App()
: m_pvx()
{}

~App()
{
for (std::vector<X* >::iterator it = m_pvx.begin();
it != m_pvx.end();
++it)
delete *it;
}

void run()
{
m_pvx.push_back (new X(std::string(" hello"), 43));
}
};

int main()
{
App().run();
}

--
Claudio Jolowicz
http://www.doc.ic.ac.uk/~cj603

Jul 22 '05 #3
"Claudio Jolowicz" <cj***@doc.ic.a c.uk> wrote in message
news:Pi******** *************** ********@kiwi.d oc.ic.ac.uk...
| On Wed, 21 Apr 2004, Nobody wrote:

|
| Yes, store pointers in the vector. For example:

[snip]

|
| class App
| {
| std::vector<X*> m_pvx;

^^^^^^^^^^^^^^^ ^^^^^^^

highly non-recommended. Use vector< shared_ptr<X> >.

br

Thorsten
Jul 22 '05 #4
"Thorsten Ottosen" <ne*****@cs.auc .dk> wrote in message
news:408703bd$0 $20662
"Claudio Jolowicz" <cj***@doc.ic.a c.uk> wrote in message

std::vector<X*> m_pvx;


highly non-recommended. Use vector< shared_ptr<X> >.


Highly non-recommended by who? I think Claudio's original solution is fine.
It uses less memory than your version (a counted_ptr is about twice the size
as a regular pointer, plus add memory for the actual integers), though
granted this may sometimes pale in comparison to the sizeof(X).

To save on the typing, it would be nice to generalize the idea to a template
class pointer_contain er<T> that holds a container<T*>, and whose destructor
deletes the items.
Jul 22 '05 #5
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote in message news:<5N******* *************@b gtnsc04-news.ops.worldn et.att.net>...
To save on the typing, it would be nice to generalize the idea to a template
class pointer_contain er<T> that holds a container<T*>, and whose destructor
deletes the items.


Hmm .. aren't there ownership issues inherent to this idea? Who is to
say that the elements in the container belong to it? Couldn't the
pointer-elements have been initialized from already existing objects,
for example the elements of another container<T*>? It seems to me
that this would only really be useful in the context of the boost
smart-pointers, where ownership is already clear, IOW

shared_ptr_cont ainer<T> for container<share d_ptr<T> >, when the
elements will be owned by the container and
weak_ptr_contai ner<T> for container<weak_ ptr<T> > when they will not.

I suppose you could do a similar thing without boost as:

owned_ptr_conta iner<T> // destructor deletes elements
view_ptr_contai ner<T> // destructor doesn't delete elements

Dave Moore
Jul 22 '05 #6
"Dave Moore" <dt*****@rijnh. nl> wrote in message
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote in message news:<5NGhc.182 57
To save on the typing, it would be nice to generalize the idea to a template class pointer_contain er<T> that holds a container<T*>, and whose destructor deletes the items.


Hmm .. aren't there ownership issues inherent to this idea? Who is to
say that the elements in the container belong to it? Couldn't the
pointer-elements have been initialized from already existing objects,
for example the elements of another container<T*>? It seems to me
that this would only really be useful in the context of the boost
smart-pointers, where ownership is already clear, IOW


Right, to make the intent clear we ought to name the container as
owned_pointer_c ontainer or something like that. But my intent was to not
use boost::shared_p tr in the implementation of my class.
shared_ptr_cont ainer<T> for container<share d_ptr<T> >, when the
elements will be owned by the container and
weak_ptr_contai ner<T> for container<weak_ ptr<T> > when they will not.

I suppose you could do a similar thing without boost as:

owned_ptr_conta iner<T> // destructor deletes elements
view_ptr_contai ner<T> // destructor doesn't delete elements


Yes, those are good names.
Jul 22 '05 #7
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote in message
news:BE******** ************@bg tnsc05-news.ops.worldn et.att.net...
owned_pointer_c ontainer or something like that. But my intent was to not
use boost::shared_p tr in the implementation of my class.


I'm a bit lost here. In your first reply to the OP, you suggested that he

"...could try smart pointers, like so:
std::vector<boo st::shared_ptr< X> > d_container;"

I assumed that in doing so you were actually recommending that he *should*
try boost::shared_p tr.

Rgds,
MikeB
Jul 22 '05 #8
"MikeB" <ob************ ***@hotmail.com > wrote in message news:c698cf$ktn $1
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote in message

owned_pointer_c ontainer or something like that. But my intent was to not use boost::shared_p tr in the implementation of my class.


I'm a bit lost here. In your first reply to the OP, you suggested that he

"...could try smart pointers, like so:
std::vector<boo st::shared_ptr< X> > d_container;"

I assumed that in doing so you were actually recommending that he *should*
try boost::shared_p tr.


I gave 2 possibilities, one vector<boost::s hared_ptr<T>> and the other
essentially vector<T*>. The owned_pointer_c ontainer method is just
vector<T*> with an interface to delete the internal items.
Jul 22 '05 #9

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

Similar topics

1
2228
by: Wolfgang Lipp | last post by:
my question is: do we need container elements for repeating elements in data-centric xml documents? or is it for some reason very advisable to introduce containers in xml documents even where not strictly needed? how can a recommendation on this in the light of existing tools like w3c xml schema and relaxng as well es established practice be answered? i would greatly appreciate any words, pointers, and links. the exposition of the...
5
1477
by: TheFerryman | last post by:
How bad is it to include a non const accessor to a container of objects? For instance template <class WheelType> class CarBase { typedef std::list<WheelType*> WheelList; private:
8
2427
by: Markus Dehmann | last post by:
I defined a base class in order to put heterogeneous values into a standard container: All values that I store in the container are derived from my base class. Now when I iterate over the elements of the container and want my original values back - can I avoid excessive casting and if statements? (see my sample code below.) Can I make it more elegant? #include <iostream> #include <vector>
3
1455
by: Peteris Krumins | last post by:
Hello! I would like to ask how to search for a container element which matches some criteria. Here is what I mean. Suppose I have a structure: struct my_struct { my_struct(const std::string &lname, const std::string &lvalue, const std::string &lothername, const bool lsomething,
0
1946
by: nick | last post by:
Hi, I need to manage a "layered" collection of objects, where each layer grows independently, e.g, o--+--+--+--+--+ 1st layer | o 2nd layer (empty) | o--+--+--+ 3rd layer |
14
2043
by: PengYu.UT | last post by:
In the following program, I want an iterator contain pointer pointing to constant object not const pointer. If it is possible would you please let me know how to do it? #include <boost/shared_ptr.hpp> #include <vector> #include <iterator> #include <iostream> class trial {
18
1821
by: Goran | last post by:
Hi @ all! Again one small question due to my shakiness of what to use... What is better / smarter? private: vector<MyClass_t* itsVector; OR...
7
3130
by: ademirzanetti | last post by:
Hi there !!! I would like to listen your opinions about inherit from a STL class like list. For example, do you think it is a good approach if I inherit from list to create something like "myList" as in the example below ? #include "Sector.h" using namespace boost;
36
2041
by: Peter Olcott | last post by:
So far the only way that I found to do this was by making a single global instance of the container class and providing access to the contained class, through this single global instance. Are there any other no-overhead ways that a contained class can access its container? The obvious choice of passing (a pointer or a reference to the container) to the contained class is not a no-overhead solution, it requires both memory and time. I am...
0
10261
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
10104
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10038
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
9912
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8934
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
7460
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
5354
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
4007
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
2850
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.