Why Can I Modify A const std::vector& ???

C

cppaddict

I'm confused about const references. I thought they provided a way to
give access to private members without allowing those members to be
changed. However, the following client code successfully deletes the
referred to member vector:

PointCollection pc;
pc.addSomePoints();
std::vector<Point> mem = pc.getPoints(); //returns a const ref
cout << mem.size() << endl; //outputs 3, or whatever # of
points happens to be
mem.clear();
cout << mem.size() << endl; //outputs 0!!

Here is the the class in question:

class PointCollection {
private:
std::vector<int> m_points;
public:
const std::vector<Point>& PointCollection::getPoints()
{
return m_points;
}
//other methods to add points, etc, left out for
brevity
}

Thanks for any help,
cpp
 
A

Alan Johnson

cppaddict said:
I'm confused about const references. I thought they provided a way to
give access to private members without allowing those members to be
changed. However, the following client code successfully deletes the
referred to member vector:

PointCollection pc;
pc.addSomePoints();
std::vector<Point> mem = pc.getPoints(); //returns a const ref
cout << mem.size() << endl; //outputs 3, or whatever # of
points happens to be
mem.clear();
cout << mem.size() << endl; //outputs 0!!

Here is the the class in question:

class PointCollection {
private:
std::vector<int> m_points;
public:
const std::vector<Point>& PointCollection::getPoints()
{
return m_points;
}
//other methods to add points, etc, left out for
brevity
}

Thanks for any help,
cpp

The following line is not doing what you think it is doing:
std::vector<Point> mem = pc.getPoints(); //returns a const ref

Your "getPoints" member may indeed be returning a constant reference,
but it is being used to initialize a vector of Points. That is, you are
making a copy (via vector's copy constructor) of whatever getPoints
returns a reference to, and then operating on that copy. If you just
want a reference you can use locally, try:
const std::vector<Point> &mem = pc.getPoints();

Alan
 
D

davidrubin

cppaddict said:
I'm confused about const references. I thought they provided a way to
give access to private members without allowing those members to be
changed. However, the following client code successfully deletes the
referred to member vector:

PointCollection pc;
pc.addSomePoints();
std::vector<Point> mem = pc.getPoints(); //returns a const ref

Here you are invoking the copy constructor on 'mem'. Now, 'mem' is a
*copy* of 'pc.getPoints()'. It is not itself a const reference. That
would look like this:

const std::vector<Point>& mem = pc.getPoints();

/david
 
C

cppaddict

Your "getPoints" member may indeed be returning a constant reference,
but it is being used to initialize a vector of Points. That is, you are
making a copy (via vector's copy constructor) of whatever getPoints
returns a reference to, and then operating on that copy. If you just
want a reference you can use locally, try:
const std::vector<Point> &mem = pc.getPoints();

Alan,

Thank you very much. That is exactly what I want.

cpp
 
C

cppaddict

One more thing...

I changed the code to:

const std::vector<Point>& mem = pc.getPoints();

and then used that ref to alter m_points. The compiler issues a
warning, but allows me to do it. And now the code really is changing
the member vector. Is const just a suggestion, rather than an
enforcable rule?

Thanks,
cpp
 
A

Andre Kostur

One more thing...

I changed the code to:

const std::vector<Point>& mem = pc.getPoints();

and then used that ref to alter m_points. The compiler issues a
warning, but allows me to do it. And now the code really is changing
the member vector. Is const just a suggestion, rather than an
enforcable rule?

Show us how you are modifying m_points, and what's the warning that the
compiler is issuing?
 
J

John Carson

cppaddict said:
One more thing...

I changed the code to:

const std::vector<Point>& mem = pc.getPoints();

and then used that ref to alter m_points. The compiler issues a
warning, but allows me to do it. And now the code really is changing
the member vector. Is const just a suggestion, rather than an
enforcable rule?

No. Using VC++ 7.1, the

mem.clear();

call won't compile for me. What compiler are you using and what is your
*exact* code.
 
C

cppaddict

No. Using VC++ 7.1, the
mem.clear();

call won't compile for me. What compiler are you using and what is your
*exact* code.

Hey John.

The following code, compiled with Borland, issues a warning on the
call to clear but compiles. The output is 3 and 0, so it is
definitley altering the member vector. "Point" is a custom class
similar to the POINT of winAPI, though I don't think it's relevant:

const std::vector<Point>& mem = pc.getPoints(); //returns a
const ref
cout << mem.size() << endl; //outputs 3, or whatever # of
mem.clear();
const std::vector<Point>& mem2 = pc.getPoints(); //returns a
const ref
cout << mem2.size() << endl; //outputs 0!!

Also, here is the signature of getPoints:

const std::vector<Point>& getPoints() const;

Thanks for any more info,
cpp
 
O

Old Wolf

cppaddict said:
The following code, compiled with Borland, issues a warning on the
call to clear but compiles. The output is 3 and 0, so it is
definitley altering the member vector.
const std::vector<Point>& mem = pc.getPoints();
mem.clear();

You should treat that compiler warning as an error.
(In C and C++, compilers are allowed to still produce some sort
of program that may not do what you intended, as long as they
produce a diagnostic message reporting the violation).
 
J

John Carson

cppaddict said:
Hey John.

The following code, compiled with Borland, issues a warning on the
call to clear but compiles. The output is 3 and 0, so it is
definitley altering the member vector. "Point" is a custom class
similar to the POINT of winAPI, though I don't think it's relevant:

const std::vector<Point>& mem = pc.getPoints(); //returns a
const ref
cout << mem.size() << endl; //outputs 3, or whatever # of
mem.clear();
const std::vector<Point>& mem2 = pc.getPoints(); //returns a
const ref
cout << mem2.size() << endl; //outputs 0!!

Also, here is the signature of getPoints:

const std::vector<Point>& getPoints() const;

Thanks for any more info,
cpp


This is simply non-compliant behaviour on the part of the compiler. It
should not compile.
 
P

Pete Becker

John said:
This is simply non-compliant behaviour on the part of the compiler. It
should not compile.

The rule is that a compiler must issue a diagnostic. There is no
requirement in the language defintion that a compiler refuse to compile
anything.
 
X

x6c6565

class PointCollection {
private:
std::vector<int> m_points;
....
}

are you sure you want this to be a vector<int> and not a vector<Point>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top