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

returning a const vector

At least that is what I think I want to do.

What is the proper way for me to return multiple data member objects
from an accessor method in my class while ensuring the data does not
get changed, but allowing iteration through the data?

I tryed returning a const vector but the compiler does not like the
idea of my using an iterator to look through the vector down the
road...I assume because an iterator acts like a pointer and allows you
to change the data?

Thanks,
Christopher

Here is my class currently:

#include <direct.h>
#include <winsock2.h>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

//------------------------------------------
class Directory
{
public:

Directory(){}
~Directory(){}

// Accessors
string & GetPath()
{
return m_path;
}

vector<Directory> & GetSubdirectories()
{
return m_subdirectories;
}

vector<string> & GetFilenames()
{
return m_filenames;
}

// Mutators

//--------------------------------
// Gather file and subdirectory info from the directory specified by
path
// Note: (recursive)
bool Set(const char * path)
{
// Make sure the path points to a valid directory
HANDLE file_handle = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA file_data;
DWORD error;

// Add the wild card character to the path to search it's
contents
string search_path(path);
search_path += "\\*";

// Search for the first file or directory in the path
file_handle = FindFirstFile(search_path.c_str(), &file_data);

// Was the supplied path a valid directory? (there would at least
be a "." or ".." found)
if(file_handle == INVALID_HANDLE_VALUE ||
!(file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
cout << path << "\n is an invalid directory. Error:" <<
GetLastError() <<endl;
FindClose(file_handle);
return false;
}
else
{
// Set this directory object's path to the supplied path
m_path = path;

// Do the following until no more files or directories are
found
do
{
// Skip the . and .. directories
if( strcmp(file_data.cFileName,".") != 0 &&
strcmp(file_data.cFileName,"..") != 0 )
{
// Check if we found a file or a directory
if(file_data.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY)
{
// Get the path to the subdirectory
Directory subdirectory;
string subdir_path(path);
subdir_path += "\\";
subdir_path += file_data.cFileName;

// Read the subdirectory's contents
subdirectory.Set(subdir_path.c_str());

// Insert the record
m_subdirectories.push_back(subdirectory);
}

// Otherwise, we found a file
else
{
// Get the filename
string filename(file_data.cFileName);

// Insert the record
m_filenames.push_back(filename);
}
}
}while(FindNextFile(file_handle, &file_data) != 0);
}

// Release the file handle
FindClose(file_handle);

return false;
}

private:

// Data
string m_path;
vector<Directory> m_subdirectories;
vector<string> m_filenames;
};

Jul 23 '05 #1
4 2379
<cp***@austin.rr.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com
At least that is what I think I want to do.

What is the proper way for me to return multiple data member objects
from an accessor method in my class while ensuring the data does not
get changed, but allowing iteration through the data?

I tryed returning a const vector but the compiler does not like the
idea of my using an iterator to look through the vector down the
road...I assume because an iterator acts like a pointer and allows you
to change the data?


Use const_iterator rather than iterator.
--
John Carson
Jul 23 '05 #2
I get this error mesage when trying to use a const_iterator

144 C:\Documents and Settings\pisz_chris\My
Documents\projects\vidparser\main.cpp passing `const Directory' as
`this' argument of `const std::string& Directory::GetPath()' discards
qualifiers

on this block

cout << "Subdirectories:\n";
for( vector<Directory>::const_iterator it =
root_dir.GetSubdirectories().begin(); it !=
root_dir.GetSubdirectories().end(); it++)
{
cout << it->GetPath() <<endl;
}

Jul 23 '05 #3
c...@austin.rr.com wrote:
At least that is what I think I want to do. [snip] vector<string> & GetFilenames()
{
return m_filenames;
}


I usually prefer to do this in a more STL-ish way. Something along the
lines of this psudocode:

template<class OutputIterator>
void Directory::GetFilenames(OutputIterator itX)
const
{
std::copy(m_filenames.begin(), m_filenames.end(), itX);
}

There are some benefits to this approach, I think. For one thing, the
signature of GetFilenames() isn't dependant on Directory's
implementation details. Therefore, clients of Diretory also aren't
dependant on Directory's implementation details -- at least,
GetFilenames() isn't a culprit here. In this case, you could change
the type of m_filenames from vector to list for example, and the
signature of GetFilenames() still needn't change.

For another, GetFilenames() imposes fewer restrictions on clients than
if it returned some sort of reference to a container. 'itX' can be
anything that is valid as an OutputIterator. It could be a
back_insert_iterator, or even just a pointer to a fixed-size C-style
array. The choice is on the client.

For yet another, this method is very easy to extend. Consider if you
chose to extend your method by adding an optional paramater that
specified wildcards. Then your function could retuyrn only those
filenames that pattern-match the wildcard. If the method is
implemented as I have above, it could simply be extended by using
'copy_if()'* instead of 'copy()'. If you implement it by returning a
reference to a vector or something like that, it might be impossible or
at least very difficult to implement.

This is also a very easy method to implement. I find that when a piece
of code is harder to write than it seems like it should be, its very
often becasue my design is wrong -- I'm trying to write a bad piece of
code. If the design is 'right', the code can practically write itself.

Take care,

John Dibling

* : regarding copy_if(). There isn't one as defined in the Standard,
but this is a very easy and useful thing to implement. See Scott
Meyers' "Effective STL" item # 36 for one implementation, or "Extending
the STL" in the February 2005 C/C++ User's Journal for another.

Jul 23 '05 #4
cp***@austin.rr.com wrote:
I get this error mesage when trying to use a const_iterator

144 C:\Documents and Settings\pisz_chris\My
Documents\projects\vidparser\main.cpp passing `const Directory' as
`this' argument of `const std::string& Directory::GetPath()' discards
qualifiers

on this block

cout << "Subdirectories:\n";
for( vector<Directory>::const_iterator it =
root_dir.GetSubdirectories().begin(); it !=
root_dir.GetSubdirectories().end(); it++)
{
cout << it->GetPath() <<endl;
}


// Accessors
const string & GetPath()const
{
return m_path;
}

one can call only const methods on a const object

Jul 23 '05 #5

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

Similar topics

4
by: Patrick | last post by:
I want to achieve the following behaviour but I am having trouble getting there...bare with me im knew to c++ , so its probably rather trivial! To have a class ClassA, and composed within this...
18
by: cppaddict | last post by:
Hi, Is it considered bad form to have the subscript operator return a const reference variable? If not, what is the proper way to do it? My question was prompted by the code below, my...
8
by: Derek | last post by:
Some authors advocate returning const objects: const Point operator+(const Point&, const Point&); ^^^^^ Returning a const object prevents some bad code from compiling: Point a, b, c; (a +...
5
by: Alfonso Morra | last post by:
Hi, What is the recomended way of returning an STL container (e.g. std::string, std::vector etc fom a function? Is it by simply returning a local variable? (I doubt it) std::string...
1
by: maadhuu | last post by:
what is the use of returning "const & "from a function in C++ ?? Is it used somewhere at all ?? thank you, Ranjan.
8
by: Richard | last post by:
what is the syntax for returning a vector? temp is a vector return temp; ? return temp<>; ? return temp<int>; ?
10
by: andrew browning | last post by:
i have overlaoded all of my arithmetic operators but all are functioning as multiplication. below is a sample of the addition operator: Rational operator + (const Rational& r1, const Rational&...
2
by: =?iso-8859-9?B?RGlu52F5IEFr5/ZyZW4=?= | last post by:
Following function void mdelr(int *ar1, int a, int b, int d ) { int i,j,tmp; int *temp; for (i=0; i<a; i++) {
23
by: pauldepstein | last post by:
Below is posted from a link for Stanford students in computer science. QUOTE BEGINS HERE Because of the risk of misuse, some experts recommend never returning a reference from a function or...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.