For my CS class I have a variable const int m_vin, throughout my code I am required to edit this value. I was under the impression that const variables cannot be edited. How would I go about this?
Edit:
Here are the directions for m_vin which is a member variable of an Object named Vehicle:
m_vin, a const int which represent a unique VIN–Vehicle Identification Number (no two vehicles can ever exist with the same m_vin).
In my program I am required to edit m_vin;
Word of caution: Modifying the value of such an object, no matter the technique used to do it, is cause for undefined behavior.
You could use:
int& ref = const_cast<int&>(m_vin);
ref = <new value>;
Don't blame me if your computer blows up.
It will be better to change the variable to be a non-const one.
int m_vin;
You should ask your professor/teaching assistant why is the const used there if the value of the variable is expected to be modified through out the code. That does not make sense.
You don't.
That's the whole point.
"For my CS class I have a variable const int m_vin, throughout my code I am required to edit this value." - Don't do that. You'll invoke Undefined Behaviour.
Create a copy. Edit the copy. Save the copy back to "wherever".
Don't try to modify const variables. Even though the language gives you tools to write code that will do it and that will compile, you will have code that has no well defined behaviour. Don't do that.
Constants (also called literals) are fixed values once declared and initialized. unlike variables whose value can be altered, constants - as the name implies does not change, they remain constant. Constant must have to be initialized at the time of creating it, and new values cannot be assigned later to it.
Consider using a variable if the value will ever change during the program execution.
Do not do this. Ever. As stated by R Sahu, you can try const_cast to remove const'ness. However, this is not the only guard to fight with. Sometimes (especially if this is a global-scope defined item), memory page that contains the const items could be marked as read-only by OS (I met such a thing on Win XP). So, your attempt to modify const_cast'ed item could end up with Access Violation or similar.
Again: do NOT do this.
For my CS class I have a variable const int m_vin, throughout my code I am required to edit this value. I was under the impression that const variables cannot be edited. How would I go about this?
As others have pointed out, you can't, at least not directly. And it's not good programming to even try.
Here are the directions for m_vin which is a member variable of an Object named Vehicle: m_vin, a const int which represent a unique VIN–Vehicle Identification Number (no two vehicles can ever exist with the same m_vin).
Most likely your instructor is asking you to construct different objects with differing const int m_vin. If you do that you don't need to edit them after construction since each object is initialized with a different vin.
In my program I am required to edit m_vin;
However, assuming this is sort of a programming challenge, you can change a const member variable by instantiating a new object initialized with the different value. This is best done in a friend function so you can access private variables.
One way to accomplish this is using placement new together with a constructor that has all values needed to initialize the object. First save copies of all the values in the object locally. Use std::move for dynamic values. Next, call the destructor on the object. Then use placement new with the argument list needed to reconstruct the object with the new const value.
The following code replaces m_vin with a different value.
#include <memory>
#include <string>
struct Foo {
const int m_vin;
std::string stuff;
Foo(int m_vin_, std::string stuff_) : m_vin{ m_vin_ }, stuff{ stuff_ } {}
~Foo() {}
};
int main()
{
Foo foo1(1, "SomeString");
int ci = 42 // modify ci
std::string stuff = foo1.stuff;
foo1.~Foo(); // in case there is any dynamic objects in Foo
new(&foo1) Foo(ci, stuff);
std::string x = foo1.stuff;
}
But be warned. You should also use std::launder to guarantee the const member will be correctly read. This sort of hack, while legal (I think), harms the readability of the code. People reading the code will, reasonably, assume that const member variables will not change after they are constructed. So don't do it other than to pacify an instructor with a weird request.
Related
today I have learned about the mutable keyword in C++ and would like to use it in my code.
I have a class with many const methods and one of them should be able to modify some of the object's variables (conserving the logical state of the object). However I don't want to let all the const methods to modify the variable, only the selected one. Is there any way of doing that? Maybe with const_cast?
(The code I am talking about is an implementation of the Union-Find structure. The Find operation does not change the logical state of the structure (it only searches for a root of a tree), but changes the physical state by doing so-called path compression)
Thanks!
EDIT: I have added an excerpt from the code I am referring to:
class UnionFind {
public:
void Union(int a, int b) {...}
int Find(int x) const {
// logically, this method is const
while(x != parents[x]) {
// path compression
// the next three lines modify parents and sizes,
// but the logical state of the object is not changed
sizes[parents[x]] -= sizes[x];
sizes[parents[parents[x]]] += sizes[x];
parents[x] = parents[parents[x]];
x = parents[x];
}
return x;
}
int someOtherMethodThatAccessesParents() const {
// this method does access parents, but read only.
// I would prefer if parents behaved like if it was
// not 'mutable' inside this method
...
}
private:
// these have to be mutable if I want the Find method
// to be marked const (as it should be)
// but making them mutable then does not enforce
// the physical non-mutability in other const methods :(
mutable std::vector<int> parents;
mutable std::vector<int> sizes;
};
On first glance this can't be achieved unless you use a nasty const_cast. But don't do that since the behaviour on attempting to modify a variable following a const_cast that was originally declared as const is undefined.
However, it might be feasible to achieve what you want using friendship since that can be controlled on a function by function basis whereas mutability, as you correctly point out, cannot be.
Put the variable you want to modify in a base class and mark it private. Perhaps provide a "getter" function to that member. That function would be const and would probably return a const reference to the member. Then make your function a friend of that base class. That function will be able to change the value of that private member.
If you can afford to use mutable, that is the right way to do it.
Still, it's possible to do what you are asking for. Normally this is done via the “fake this” idiom:
MyClass *mutableThis = const_cast<MyClass*>(this);
Then access your field normally through the new pointer. This is also the way to do it if you have to support some old compiler with no mutable support.
Note however that this is generally a dangerous practice, as it can easily lead you into the dreaded realm of undefined behavior. If the original object was actually declared const (as opposed to just being accessed via a const pointer/reference), you're asking for trouble.
In short: use mutable when you can, use fake this when you can't, but only when you know what you're doing.
In following example const object can modify itself via const method, because in that method it acces itself via non-const pointer. (same program on ideone)
#include <iostream>
struct Object;
Object * g_pObject;
struct Object
{
Object():m_a(0){}
void ModifySelfViaConstMethod() const
{
g_pObject->m_a = 37;
}
int m_a;
};
int main()
{
Object o;
g_pObject = &o;
const Object & co = o;
std::cout << co.m_a << "\n";
co.ModifySelfViaConstMethod();
std::cout << co.m_a << "\n";
return 0;
}
I am not so good with reading c++ standard, so I ask here:
What does standard says about this?
a)const method doesn't guarantee you that your object stays unmodified when you do stuff like this
b) Is it well defined that and it must compile
c) other ?
When you declare a const function, it's "for your own good".
In other words, you declare it const because according to your initial design, it is not supposed to change any object with which it will be invoked during runtime.
If during some later point in the implementation of this function you end up changing the object, the compiler will "yell at you", telling you it's wrong.
Of course, the compiler will be able to identify such attempt, only when applied on this.
In the given example, the compiler cannot identify the problem because it requires a comparison between this and g_pObject, and such comparison can only take place during runtime.
When a method is declared as const, the compiler ensures that the instance pointed to by the this pointer is not modified. If you try to modify the this instance, the compiler to fail. However, the compiler has no way of knowing that g_pObject and this are actually pointing at the same instance. That requires a run-time comparison, and no compiler is going to waste time performing run-time comparisons of every pointer used inside of a const method in the off-chance that they might match the this pointer. So if you are going to modify an Object via an external pointer, you are going to have to do your own check, eg:
void ModifySelfViaConstMethod() const
{
if (g_pObject != this)
g_pObject->m_a = 37;
}
What does standard says about this?
It says (paraphrasing) that this has type const Object *, so that you can't directly modify members or call non-const member functions via this. It says nothing about what you can do with any global variables that the function might have access to; it only controls direct access to the object the function is called on.
const method doesn't guarantee you that your object stays unmodified when you do stuff like this
No it doesn't. It states the intent that the function won't modify the object, and provides some protection against accidentally breaking that intent. It doesn't prevent a suitably deranged programmer from using const_cast, or (as here) uncontrolled coupling via global variables to break the promise.
Is it well defined that and it must compile
Yes. o is not itself constant, so there's nothing to stop you taking a non-const pointer or reference to it. The const on the member function only restricts access to the object via this, not to arbitrary objects via other pointers.
Constancy in C++ is a safety instrument, not security.
The code where constancy is honored will most probably work as expected, and all unintentional attempts to cast constancy away will be alerted by the compiler.
In cases when "I know what I am doing" one can find the whole variety of tools, from const_cast operator and mutable keyword to the banal C style cast.
I have had to simplify some of my code to ask this question. However, in the below code does the fact that I am not declaring x as a reference type mean my change of decrementing will get "forgotten" once the function has exited?
The smartest way to fix this would be to declare x as AnotherClass& x?
void MyClass::myFunc(unordered_map<int, AnotherClass>* dictionary, int z, int y){
AnotherClass x = dictionary->at(z);
//Does this change on x get "forgotten" in terms of what dictionary stores
//once myFunc() has finished, because x is not a reference/pointer type?
x.changeSomething(y--);
}
class MyClass{
public:
private:
myFunc(unordered_map<int, AnotherClass>* dictionary, int z);
unordered_map<int, AnotherClass>* dictionary
};
Correct. x is a copy of an element of dictionary. You are applying changes to the copy, which is local to the function. You should see no effects in the caller side. You can either take a reference, or act directly on the result of the call to at:
dictionary->at(z).changeSomething(z--);
Note that this has nothing to do with the code being inside a function.
In languages like Java or C# when you write Thing t = s; you are actually creating an alias t that refer to the same object in memory than s refer to. In C++, however, values and aliases are strictly separated:
Thing t = s; is about making a copy of s
Thing& t = s; is about creating an alias referring to the same object than s (a reference)
Thing* t = &s; is about creating an alias referring to the same object than s (a pointer)
The difference between references and pointers does not matter here, what matters is the difference between copies and aliases.
Changes to a copy are local to that copy
Changes to an object via an alias are local to that object, and visible through all aliases referring to that object
In term of your example:
// Fix 1: take dictionary by *reference* and not by *pointer*.
void MyClass::myFunc(std::unordered_map<int, AnotherClass>& dictionary, int z, int y){
// Fix 2: dictionary.at(z) returns a "AnotherClass&"
// that is an alias to the element held within the dictionary.
// Make sure not to accidentally make a copy by using that "&"
// for the type of x.
AnotherClass& x = dictionary.at(z);
// "x" is now a mere alias, the following call is thus applied
// to the value associated to "z" within "dictionary".
x.changeSomething(y--);
}
Note that you could write dictionary.at(z).changeSomething(y--); in this case; however there are several shortcomings:
if x is reused more then once, naming it makes it clearer.
in cases where the function/method invoked have side-effects, the number of calls is important and need be controlled.
from a performance point of view, avoiding unnecessary computing the same thing over and over is always welcome... but don't get too hang up on performance ;)
I apologize if the title sounds abstruse, let me make that simple with an example :
class A
{
public:
A(int *flag) : flag_(flag) {}
void foo();
private:
void bar();
int *flag_;
};
The question is: can I prevent this class from changing the value pointed to by flag_?
Note : I'm thinking, maybe I want to write something like const int * flag_, but I do not want to make the value pointed to by flag "irrevocably" constant. In my case, this value is the value of some member variable of some other class, which can be changed.
Thanks for your insights!
const int *flag_; will not modify the constness of the actual variable passed in, it just defines how flag_ can be used. Whatever you pass into A's constructor will not have its constness changed. const isn't a runtime change, it's merely syntax to prevent the coder from accidentally modifying a value. You can do yourself one better and make it const int *const flag_; which will prevent A from modifying *flag_ AND flag_ won't be reassignable.
The question is: can I prevent this class from changing the value pointed to by flag_?
Note : I'm thinking, maybe I want to write something like const int * flag_, but I do not want to make the value pointed to by flag "irrevocably" constant.
So... you want it to be constant... except for when you don't? No, I don't see a solution to that. You, as the class maintaner, can maintain the invariant that flag_ is only changed under X condition(s).
EDIT: I think I misunderstood you. Just make the pointer const (or what it points to const). That doesn't have any affect on the other member variable, it simply controls how field_ is used.
On a side note, is it safe to store the address of this member of another class? What happens if the instance of the other class is moved (stored in any vectors? There are many cases in which it could be moved, invalidating your pointer)? What happens if the instance is allocated with automatic storage duration and goes out of scope? It's fine to store a pointer member if you really need to (do you?), but there are things you need to consider.
Without using const then no you cannot. But if class A declares the flag pointer as const, that should have not affect another class that has a pointer to the same memory location from modifying the value.
The int* flag_, is a private member;
Your class's client user can't change flag_ and flag_ pointed to.
Now This is your class .
Don't design to write any code like : *flag_=14;
The Scott Meyers's "Effective c++" has a few thing you want to know.
I am programming in C++ more then 5 years, and have never met any place where reference of the variable is recommended to use except as a function argument (if you don't want to copy what you pass as your function argument). So could someone point cases where C++ variable reference is recommended (I mean it gives any advantage) to use.
As a return value of an opaque collection accessor/mutator
The operator[] of std::map returns a reference.
To shorten the text needed to reference a variable
If you miss old-school with Foo do ... statement (that's Pascal syntax), you can write
MyString &name = a->very->long_->accessor->to->member;
if (name.upcase() == "JOHN") {
name += " Smith";
}
another example of this can be found in Mike Dunlavey's answer
To state that something is just a reference
References are also useful in wrapper objects and functors--i.e. in intermediate objects that logically contact no members but only references to them.
Example:
class User_Filter{
std::list<User> const& stop_list;
public: Functor (std::list<User> const& lst)
: stop_list(lst) { }
public: bool operator()(User const& u) const
{ return stop_list.exists(u); }
};
find_if(x.begin(),x.end(),User_Filter(user_list));
The idea here that it's a compile error if you don't initialize a reference in constructor of such an object. The more checks in compile time--the better programs are.
Here's a case where it's handy:
MyClass myArray[N];
for (int i = 0; i < N; i++){
MyClass& a = myArray[i];
// in code here, use a instead of myArray[i], i.e.
a.Member = Value;
}
Use references wherever you want, pointers when you are forced to.
References and pointers share part of their semantics: they are an alias to an element that is not present. The main difference is with memory managements: references express clearly that you are not responsible for the resource. On the other hand, with pointers it is never really clear (unless you mean smart pointers): are you assumed to delete the pointer or will it be deleted externally?
You must use pointers when you must manage memory, want to allow for optional semantics or need to change the element referred to at a later time.
In the rest of cases, where you can use a reference or a pointer, references are clearer and should be preferred.
Now, as you point out, they are really not needed: you can always use pointers for all the reference uses (even parameter passing), but the fact that you can use a single tool for everything does not mean there are no better suited tools for the job.
I tend to use reference members instead of pointers for externally controlled non-optional construction parameters.
EDIT (added example):
Let's say that you have a database and a DAO class having the database as a dependency:
struct Database {};
struct PersonDao {
const Database &m_d;
PersonDao(const Database &d): m_d(d) {}
};
Furthermore, the scope of the database is controlled externally from the DAO:
int main() {
Database d;
PersonDao pd(d);
}
In this case it makes sense to use a reference type, since you don't ever want DAO::m_d to be null, and its lifetime is controlled externally (from the main function in this case).
I use references in function arguments not just to avoid copies but also instead of pointers to avoid having to deal with NULL pointers where appropriate. Pointers model a "maybe there's a value, but maybe not (NULL)", references are a clear statement that a value is required.
... and to make it absolutely clear (-> comments). I tend to avoid pointers to model "maybe there are several values" - a vector is a better option here. Pointers to several values often end up in C-style programming because you usually have to pass the # of elements as well separately.
Use a const reference to give a name to a value, e.g.:
const Vec3 &ba=b-a;
This names the value, but doesn't necessarily create a variable for it. In theory, this gives the compiler more leeway and may allow it to avoid some copy constructor calls.
(Related non-duplicated Stack Overflow question at Const reference to temporary. The Herb Sutter link there has more information about this.)
The argument to the copy-constructor MUST be passed as a reference, since otherwise the copy constructor would need to call it self in an endless recursion (stack overflow).
I tend to agree, but perhaps const return values.
Well you kind of have two choices for aliasing other values(ignoring shared_ptrs and the like): pointers and references.
References must be initialized at construction to refer to something else. So semantically a reference can never be NULL. In reality, though, the underlying data can go away, giving you problems often more difficult to debug than if a pointer went away. So I'm not sure there's a real advantage here unless you were disciplined and consistent with how they were used vis-a-vis referring to items that were dynamically allocated. If you did this with pointers too, you'd avoid the same problems.
Perhaps more importantly, references can be used without thinking about all the issues that arise with pointers. This is probably the main advantage. Semantically a reference is the thing. If you guarantee as the caller/callee that the underlying memory doesn't go away, you don't have to confuse the user with any of the questions that come along with pointers (Do I need to free this? Could this be NULL? etc) and can safely use a reference for convenience.
An example of this might be a function that looks up the corresponding string for an enum,
const std::string& ConvertToString( someEnum val)
{
static std::vector< std::string > lookupTable;
if (lookupTable.empty())
{
// fill in lookup table
}
// ignoring the cast that would need to happen
return lookupTable[val]
}
Here the contract between the caller and the callee guarantees that the return type will always be there. You can safely return a reference, and avoid some of the questions that pointers invite.
References make code prettier. So use them whenever it takes a reference to beautify your code.
i would like to enlist some cases:
1) while writing singleton classes
class singleton
{
singleton();
explicit singleton(const singleton&);
singleton& operator=(const singleton&);
public:
static singleton& instance()
{
static singleton inst;
return inst;
}
};// this is called the 'Meyers' singleton pattern. refer to More Effective C++ by Scott Meyers
it has all the benefits, but avoids using the new operator
**2)**here is no such thing as a null reference. A reference must always refer to some object. As a result, if you have a variable whose purpose is to refer to another object, but it is possible that there might not be an object to refer to, you should make the variable a pointer, because then you can set it to null. On the other hand, if the variable must always refer to an object, i.e., if your design does not allow for the possibility that the variable is null, you should probably make the variable a reference
**3)**Because a reference must refer to an object, C++ requires that references be initialized:
string& rs; // error! References must
// be initialized
string s("xyzzy");
string& rs = s; // okay, rs refers to s
Pointers are subject to no such restriction
The fact that there is no such thing as a null reference implies that it can be more efficient to use references than to use pointers. That's because there's no need to test the validity of a reference before using it
**4)**Another important difference between pointers and references is that pointers may be reassigned to refer to different objects. A reference, however, always refers to the object with which it is initialized: ¤ Item M1, P10
string s1("Nancy");
string s2("Clancy");
string& rs = s1; // rs refers to s1
string *ps = &s1; // ps points to s1
rs = s2; // rs still refers to s1,
// but s1's value is now
// "Clancy"
ps = &s2; // ps now points to s2;
// s1 is unchanged
Stream operators are an obvious example
std::ostream & operator<< (std::ostream &, MyClass const &...) {
....
}
mystream << myClassVariable;
You obviously don't want a pointer as checking for NULL makes using an operator very tedious i.s.o. convenient
I've used a reference to an ostream instead of a pointer. I supppose that I prefer references to pointers when the class has a lot of operators.