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. 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/
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();
}
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/
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.
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.
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/
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/
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
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/ This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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?
|
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)...
|
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...
|
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...
|
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"
| |
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...
|
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;
|
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...
|
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
|
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...
|
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...
| |
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...
|
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,...
|
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...
|
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();...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
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...
| | |