473,782 Members | 2,419 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

using map, list etc. in const methods

Hello,

I'm quite new to C++ so maybe there's something I miss.
I write a simple board game. It has a board class. This class has a
method that returns the count of pieces a player has on the board. Since
this function does not change anything in the class I declared it as
const. To count all pieces of a given color the functions iterates
through a "map" of CNode-pointers. "CNode" is another class that is
irrelevant to the problem.

Here comes the function: (EColor is an enum of colors, not important here)

int
CBoard::countPi eces(EColor color) const
{
// "nodes" is a private class member
// with type map<string,CNod e*>
int count = 0;
for (map<string,CNo de*>::iterator i=nodes.begin() ;
i != nodes.end();
i++)
{
// do something with (*i)
// ...
}
return count;
}

The compiler refuses to compile the code, because I violate the
constness of the function in the line where I declare the iterator.
Is there a proper way (or workaround) to leave the function const?

Another point: I've heard, that it is not good to store pointers to
objects in stl-containers like map, list, vector etc. because of
ownership problems (?). Do you know a good webpage or tutorial about
this topic? I would like to learn how to do it the right way.
There are a lot of classes in the STL and I would like to know how to
use their whole power. At the moment I'm just using lists, vectors and
maps in lack of a good book or online tutorial discussing the STL in detail.

Thanks in advance!

--
Regards,
Christof Krueger

Remove "donotspam" if you want to email me.
Jul 22 '05 #1
12 1934
In article <bu************ *@news.t-online.com>, Christof Krueger wrote:
Hello,

I'm quite new to C++ so maybe there's something I miss.
I write a simple board game. It has a board class. This class has a
method that returns the count of pieces a player has on the board. Since
this function does not change anything in the class I declared it as
const. To count all pieces of a given color the functions iterates
through a "map" of CNode-pointers. "CNode" is another class that is
irrelevant to the problem.

Here comes the function: (EColor is an enum of colors, not important here)

int
CBoard::countPi eces(EColor color) const
{
// "nodes" is a private class member
// with type map<string,CNod e*>
int count = 0;
for (map<string,CNo de*>::iterator i=nodes.begin() ;
i != nodes.end();
i++)
{
// do something with (*i)
// ...
}
return count;
}

The compiler refuses to compile the code, because I violate the
constness of the function in the line where I declare the iterator.
Is there a proper way (or workaround) to leave the function const?
map<string,CNod e*>::const_iter ator

btw, you can do this using

count_if(themap .begin(),themap .end(),isWhite) ; // isWhite returns true if the piece is white
Another point: I've heard, that it is not good to store pointers to
objects in stl-containers like map, list, vector etc. because of
ownership problems (?).
It's not necessarily a bad thing. But you need to make sure that you understand
who "owns" a given pointer, and you need to make sure that the map doesn't hold
on to "dead pointers".

Here's my question: how are your pointers allocated and deleted ? Who owns them ?
Do you know a good webpage or tutorial about
this topic? I would like to learn how to do it the right way.
This topic is too complicated to be discussed exhaustively in "a webpage". You
need to read a couple of good books that deal with memory management issues.
There are a lot of classes in the STL and I would like to know how to
use their whole power. At the moment I'm just using lists, vectors and
maps in lack of a good book or online tutorial discussing the STL in detail.


Two good books about the C++ standard library:

"Accelerate d C++" Koenig and Moo
"The Standard C++ Library A Tutorial and a Reference" Josuttis

Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
Jul 22 '05 #2
Christof Krueger wrote:
Hello,

I'm quite new to C++ so maybe there's something I miss.
I write a simple board game. It has a board class. This class has a
method that returns the count of pieces a player has on the board. Since
this function does not change anything in the class I declared it as
const. To count all pieces of a given color the functions iterates
through a "map" of CNode-pointers. "CNode" is another class that is
irrelevant to the problem.

Here comes the function: (EColor is an enum of colors, not important here)

int
CBoard::countPi eces(EColor color) const
{
// "nodes" is a private class member
// with type map<string,CNod e*>
int count = 0;
for (map<string,CNo de*>::iterator i=nodes.begin() ;
i != nodes.end();
i++)
{
// do something with (*i)
// ...
}
return count;
}

The compiler refuses to compile the code, because I violate the
constness of the function in the line where I declare the iterator.
Is there a proper way (or workaround) to leave the function const?

Another point: I've heard, that it is not good to store pointers to
objects in stl-containers like map, list, vector etc. because of
ownership problems (?). Do you know a good webpage or tutorial about
this topic? I would like to learn how to do it the right way.
There are a lot of classes in the STL and I would like to know how to
use their whole power. At the moment I'm just using lists, vectors and
maps in lack of a good book or online tutorial discussing the STL in
detail.

Thanks in advance!


use const_iterator.

for (map<string,CNo de*>::const_ite rator i = nodes.begin(); ...

Also, you should use ++i instead of i++, for reasons of style and
efficiency (no need to copy the "old" state of the iterator).

You might also want to look into using std::for_each()

e.g.:

class my_counter : public std::unary_func tion<
std::pair<strin g,CNode*>,
void >
{
private:
mutable int count;
public:
my_counter() : count(0) { }
void operator()(cons t std::pair<strin g,CNode*>& val) const
{
// do something here that manipulates count
}
int get_count() const { return count; }
};

int CBoard::countPi eces(EColor color)
{
return std::for_each(n odes.begin(),
nodes.end(),
my_counter()).g et_count();
}
Jul 22 '05 #3
Christof Krueger wrote in news:bu******** *****@news.t-online.com:

[snip]

int
CBoard::countPi eces(EColor color) const
{
// "nodes" is a private class member
// with type map<string,CNod e*>
int count = 0;
for (map<string,CNo de*>::iterator i=nodes.begin() ;
for ( map<string,CNod e*>::const_iter ator i=nodes.begin() ;
i != nodes.end();
i++)
{
// do something with (*i)
// ...
}
return count;
}

The compiler refuses to compile the code, because I violate the
constness of the function in the line where I declare the iterator.
Is there a proper way (or workaround) to leave the function const?
Your problem is that when you call nodes.begin() your calling
the const version that returns a const_iterator. a const_iterator
like a pointer to a const doesn't allow you to modify the item
that its iterating (pointing) to.

Another point: I've heard, that it is not good to store pointers to
objects in stl-containers like map, list, vector etc. because of
ownership problems (?).
Look into smart pointers, in particular boost::shared_p tr:
http://www.boost.org/libs/smart_ptr/shared_ptr.htm

Do you know a good webpage or tutorial about
this topic? I would like to learn how to do it the right way.
There are a lot of classes in the STL and I would like to know how to
use their whole power. At the moment I'm just using lists, vectors and
maps in lack of a good book or online tutorial discussing the STL in
detail.


No, mostly people around hear recomend geting a good book.
Accelerated C++ (Koenig & moo) is most recomended book for this.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #4
Donovan Rebbechi wrote:
In article <bu************ *@news.t-online.com>, Christof Krueger wrote:
Hello,

I'm quite new to C++ so maybe there's something I miss.
I write a simple board game. It has a board class. This class has a
method that returns the count of pieces a player has on the board. Since
this function does not change anything in the class I declared it as
const. To count all pieces of a given color the functions iterates
through a "map" of CNode-pointers. "CNode" is another class that is
irrelevant to the problem.

Here comes the function: (EColor is an enum of colors, not important here)

int
CBoard::count Pieces(EColor color) const
{
// "nodes" is a private class member
// with type map<string,CNod e*>
int count = 0;
for (map<string,CNo de*>::iterator i=nodes.begin() ;
i != nodes.end();
i++)
{
// do something with (*i)
// ...
}
return count;
}

The compiler refuses to compile the code, because I violate the
constness of the function in the line where I declare the iterator.
Is there a proper way (or workaround) to leave the function const?

map<string,CNod e*>::const_iter ator

thanks, that makes sense :)
btw, you can do this using

count_if(themap .begin(),themap .end(),isWhite) ; // isWhite returns true if the piece is white very handy. I'll use it.
Another point: I've heard, that it is not good to store pointers to
objects in stl-containers like map, list, vector etc. because of
ownership problems (?).

It's not necessarily a bad thing. But you need to make sure that you understand
who "owns" a given pointer, and you need to make sure that the map doesn't hold
on to "dead pointers".

Here's my question: how are your pointers allocated and deleted ? Who owns them ?

In this case the board creates the nodes, stores them in the map and
deletes them in it's destructor. I see that ownership is a question of
design. Thanks!

Do you know a good webpage or tutorial about
this topic? I would like to learn how to do it the right way.

This topic is too complicated to be discussed exhaustively in "a webpage". You
need to read a couple of good books that deal with memory management issues.

There are a lot of classes in the STL and I would like to know how to
use their whole power. At the moment I'm just using lists, vectors and
maps in lack of a good book or online tutorial discussing the STL in detail.

Two good books about the C++ standard library:

"Accelerate d C++" Koenig and Moo
"The Standard C++ Library A Tutorial and a Reference" Josuttis

I'll take a look on Josuttis book.
Another question:
If I had a public method getNodeMap() that should return my nodes-map to
the caller, is there a possibility to make this method const and to
return a const version of the map, so that the caller may not change the
returned map? I tried that once, but failed because of a lot of compiler
errors.

--
Regards,
Christof Krueger

Remove "donotspam" if you want to email me.
Jul 22 '05 #5
red floyd wrote:
Christof Krueger wrote:
Hello,

I'm quite new to C++ so maybe there's something I miss.
I write a simple board game. It has a board class. This class has a
method that returns the count of pieces a player has on the board.
Since this function does not change anything in the class I declared
it as const. To count all pieces of a given color the functions
iterates through a "map" of CNode-pointers. "CNode" is another class
that is irrelevant to the problem.

Here comes the function: (EColor is an enum of colors, not important
here)

int
CBoard::countPi eces(EColor color) const
{
// "nodes" is a private class member
// with type map<string,CNod e*>
int count = 0;
for (map<string,CNo de*>::iterator i=nodes.begin() ;
i != nodes.end();
i++)
{
// do something with (*i)
// ...
}
return count;
}

The compiler refuses to compile the code, because I violate the
constness of the function in the line where I declare the iterator.
Is there a proper way (or workaround) to leave the function const?

Another point: I've heard, that it is not good to store pointers to
objects in stl-containers like map, list, vector etc. because of
ownership problems (?). Do you know a good webpage or tutorial about
this topic? I would like to learn how to do it the right way.
There are a lot of classes in the STL and I would like to know how to
use their whole power. At the moment I'm just using lists, vectors and
maps in lack of a good book or online tutorial discussing the STL in
detail.

Thanks in advance!

use const_iterator.

for (map<string,CNo de*>::const_ite rator i = nodes.begin(); ...

Also, you should use ++i instead of i++, for reasons of style and
efficiency (no need to copy the "old" state of the iterator).

I always thought that i++ is equivalent to ++i in a for loop. Could you
give more detail what the difference is since I do not understand what
you mean by saying "no need to copy the "old" state of the iterator".
Are there cases where it would be nessecary to use i++ though?

You might also want to look into using std::for_each()

e.g.:

class my_counter : public std::unary_func tion<
std::pair<strin g,CNode*>,
void >
{
private:
mutable int count;
public:
my_counter() : count(0) { }
void operator()(cons t std::pair<strin g,CNode*>& val) const
{
// do something here that manipulates count
}
int get_count() const { return count; }
};

int CBoard::countPi eces(EColor color)
{
return std::for_each(n odes.begin(),
nodes.end(),
my_counter()).g et_count();
}

I don't understand why std::for_each(. ..) returns a my_counter object in
this case. Could you explain it to me pleas (or just give me a hint so I
can look it up myself)?
--
Regards,
Christof Krueger

Remove "donotspam" if you want to email me.
Jul 22 '05 #6
In article <bu************ *@news.t-online.com>, Christof Krueger wrote:
Donovan Rebbechi wrote:
It's not necessarily a bad thing. But you need to make sure that you understand
who "owns" a given pointer, and you need to make sure that the map doesn't hold
on to "dead pointers".

Here's my question: how are your pointers allocated and deleted ? Who owns them ?

In this case the board creates the nodes, stores them in the map and
deletes them in it's destructor. I see that ownership is a question of
design. Thanks!


I see.

But why not instead store the node in an automatic structure:

class Handle
{
Node* impl;
public:
Handle(Node* x):impl(x) {}
/*
how you "handle" these is up to you ...
Handle (const Handle& );
Handle& operator= (const Handle&);
*/
~Handle() { delete impl; }
Node& operator*() { return *impl; }
const Node& operator*() const { return *impl; }
Node* operator->(){ return impl; }
const Node* operator->() const { return impl; }
};
Another question:
If I had a public method getNodeMap() that should return my nodes-map to
the caller, is there a possibility to make this method const and to
return a const version of the map,


You could make the function return a const reference to the map. But that's
a bad idea because it reveals implementation details.

A better approach would be to have begin() and end() methods that return
const_iterators and use a typedef to make it looks as though the map iterators
"belong" to the board class.

e.g.
class Board
{
std::map<foo,ba r> m;
public:
typedef std::map< foo, bar>::const_ite rator const_iterator;

const_iterator begin() const { return m.begin(); }
const_iterator end() const { return m.end(); }
Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
Jul 22 '05 #7
In article <bu************ *@news.t-online.com>, Christof Krueger wrote:
I don't understand why std::for_each(. ..) returns a my_counter object in
this case.


It does in case you want to do a post-mortem on the state of the object, as
he shows.

However, storing state in function objects like this is a hideous abomination
which can cause all kinds of subtle errors [ see Herb Sutter: More Exceptional C++).
I'd recommend steering clear of this. "red_floyd" is either a troll, or knows
just enough to be really dangerous.

Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
Jul 22 '05 #8
Donovan Rebbechi wrote:
But why not instead store the node in an automatic structure:

class Handle
{
Node* impl;
public:
Handle(Node* x):impl(x) {}
/*
how you "handle" these is up to you ...
Handle (const Handle& );
Handle& operator= (const Handle&);
*/
~Handle() { delete impl; }
Node& operator*() { return *impl; }
const Node& operator*() const { return *impl; }
Node* operator->(){ return impl; }
const Node* operator->() const { return impl; }
};


Why not just use a std::auto_ptr?

--
Andrew
Jul 22 '05 #9
In article <CijQb.241071$J Q1.135987@pd7tw 1no>, Andrew Taylor wrote:
Donovan Rebbechi wrote:
But why not instead store the node in an automatic structure:

class Handle
{
Node* impl;
public:
Handle(Node* x):impl(x) {}
/*
how you "handle" these is up to you ...
Handle (const Handle& );
Handle& operator= (const Handle&);
*/
~Handle() { delete impl; }
Node& operator*() { return *impl; }
const Node& operator*() const { return *impl; }
Node* operator->(){ return impl; }
const Node* operator->() const { return impl; }
};


Why not just use a std::auto_ptr?


Because he's storing it in a std::map. auto_ptr doesn't play nice with
standard containers because copy construct and copy-assign modify their
arguments.

For example, this doesn't compile:

std::map<int, std::auto_ptr<i nt> > m;
std::map<int, std::auto_ptr<i nt> > n(m);

To "play nice" with containers, you'd a smart pointer that had non-modifying
copy operations (like a reference counted pointer, or a deep-copy pointer)

Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
Jul 22 '05 #10

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

Similar topics

8
2848
by: JustSomeGuy | last post by:
I need to write an new class derived from the list class. This class stores data in the list to the disk if an object that is added to the list is over 1K in size. What methods of the std stl list class must Ioverride in order for this to work?
3
24036
by: Random Person | last post by:
Does anyone know how to use VBA to relink tables between two MS Access databases? We have two databases, one with VBA code and the other with data tables. The tables are referenced by linked tables in the database where the code resides. If we move the database with the data tables to a new directory, the links are no longer valid. I tried to update the links by changing the Connect property and refreshing: Set td = db.TableDefs(0)...
5
7386
by: Colin Anderson | last post by:
I discovered, with great excitement, this article http://www.davison.uk.net/vb2notes.asp when researching methods for emailing from Access via Notes. Unfortunatly, when I run this I get a Run-time error. When I run it on an XP machine it crashes, but on an NT box it just generates an unknown error, handled by the error handler. I have debugged and stepped through the code and have narrowed the issue to the point at which the...
11
6601
by: Grasshopper | last post by:
Hi, I am automating Access reports to PDF using PDF Writer 6.0. I've created a DTS package to run the reports and schedule a job to run this DTS package. If I PC Anywhere into the server on where the job is running, the job runs sucessfully, PDF files got generated, everything is good. If I scheduled the job to run at the time that I am not logged into the server, Access is not able to print to the printer. The error is pretty...
1
4010
by: Daveyk0 | last post by:
Hello there, I have a front end database that I have recently made very many changes to to allow off-line use. I keep copies of the databases on my hard drive and link to them rather than the live databases on the network. Is there a way, via code, when I get back in-house from being on the road to click a button, and select the backends I want to link to? I would want to delete all the current links and link to the "live"
6
17205
by: ransoma22 | last post by:
I developing an application that receive SMS from a connected GSM handphone, e.g Siemens M55, Nokia 6230,etc through the data cable. The application(VB.NET) will receive the SMS automatically, process and output to the screen in my application when a message arrived. But the problem is how do I read the SMS message immediately when it arrived without my handphone BeEPINg for new message ? I read up the AT commands, but when getting down...
7
2958
by: fakeprogress | last post by:
For a homework assignment in my Data Structures/C++ class, I have to create the interface and implementation for a class called Book, create objects within the class, and process transactions that manipulate (and report on) members of the class. Interface consists of: - 5 private variables char author; char title; char code;
1
3377
by: Homeworkboy | last post by:
Can anyone help me with this program? Look at the bottom of this program for help methods: /*1. Make a program that uses numbers from 1 to 100 including each ends which puts the even integers in the front of a double linked queue and the odd numbers in the back. Then prints out the deque. 2. Make a new deque list 2 that contain integers from 51 to 100. Print that list out as mine looks. Sort that list in decending order then print...
45
18904
by: Zytan | last post by:
This returns the following error: "Cannot modify the return value of 'System.Collections.Generic.List<MyStruct>.this' because it is not a variable" and I have no idea why! Do lists return copies of their elements? Why can't I change the element itself? class Program { private struct MyStruct
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
10313
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
10147
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
10081
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
9946
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
6735
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?
2
3643
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2875
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.