Difference between revisions of "Const"
(→External References) |
|||
(18 intermediate revisions by the same user not shown) | |||
Line 14: | Line 14: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Without the <code>const</code>, the operation would store the value 1 in the variable <code>defcon</code>, then the value of defcon would convert to the boolean value <code>true</code>, and the world would be fucked! This is just a simple example; proper use of <code>const</code> can solidify your code in many ways. | + | Without the <code>const</code>, the operation would store the value 1 in the variable <code>defcon</code>, then the value of defcon would convert to the boolean value <code>true</code>, and the world would be fucked! This is just a simple example; proper use of <code>const</code> can solidify your code in many ways. This is called 'const-correctness'. |
− | == Use | + | == Use Situations == |
There are a number of different situations where you can use <code>const</code>, and the meaning of the keyword changes somewhat depending on the situation. | There are a number of different situations where you can use <code>const</code>, and the meaning of the keyword changes somewhat depending on the situation. | ||
Line 24: | Line 24: | ||
<code>const int x = 69;</code> | <code>const int x = 69;</code> | ||
− | When a variable is declared in this manner, operations that modify the variable will cause a compiler error. It will also be impossible to pass a pointer or reference of that variable, unless the pointer or reference is also <code>const</code>. | + | When a variable is declared in this manner, operations that modify the variable will cause a compiler error. It will also be impossible to pass a pointer or reference of that variable, unless the pointer or reference is also <code>const</code>. Note that you must assign a const variable a value upon creation, since it will not be possible to assign one afterwards. |
=== References === | === References === | ||
Line 31: | Line 31: | ||
<code>const int& x_ref = x;</code> | <code>const int& x_ref = x;</code> | ||
− | This is especially useful in function | + | This is especially useful in function parameters, where we want to pass an object by reference (we don't wanna copy the whole damn thing!), but we aren't going to be modifying it: |
<code>void DoSomeShit( const MyObjectType& obj );</code> | <code>void DoSomeShit( const MyObjectType& obj );</code> | ||
Line 40: | Line 40: | ||
Much like references, you can declare const pointers that are not allowed to modify their targets. | Much like references, you can declare const pointers that are not allowed to modify their targets. | ||
− | <code>const int | + | <code>const int* px = &x;</code><br /> |
− | <code>void DoSomeShit( const MyObjectType& obj );</code> | + | <code>void DoSomeShit( const MyObjectType* obj );</code> |
+ | |||
+ | We sometimes call these 'pointer-to-const' because it is the object that they point to that is not modifiable. There is another kind of <code>const</code> pointer, defined like this: | ||
+ | |||
+ | <code>int* const px = &x;</code> | ||
+ | |||
+ | This kind of <code>const</code> pointer is not retargettable. So here it is the pointer itself that is being locked down. You can also have both! | ||
+ | |||
+ | <code>const int* const px = &x;</code> | ||
+ | |||
+ | This pointer cannot be retargetted, and it cannot modify its target. | ||
+ | |||
+ | === Member Functions === | ||
+ | Member functions can also be declared as const. You might think that makes no goddamn sense, a function doesn't store anything--it can't be modified! But here the meaning is a bit different. | ||
+ | |||
+ | <code>void MyMemberFunc() const;</code> | ||
+ | |||
+ | When you make a member function <code>const</code>, what you're saying is "this function will not modify the object on which it is called". This gives you two benefits: first of all, the compiler will tell you if you unintentionally do something that could modify the object inside of the function, and secondly, it allows you to call that member function even on objects that are <code>const</code>! | ||
+ | |||
+ | <syntaxhighlight lang="cpp" line="1" > | ||
+ | class MyClass | ||
+ | { | ||
+ | public: | ||
+ | void MyConstFunc() const; | ||
+ | void MyFunc(); | ||
+ | }; | ||
+ | |||
+ | MyClass myObj; | ||
+ | myObj.MyFunc(); // fine | ||
+ | myObj.MyConstFunc(); // fine | ||
+ | |||
+ | const MyClass myObj_const; | ||
+ | myObj_const.MyFunc(); // GET FUKT M8!! | ||
+ | myObj_const.MyConstFunc(); // fine, const func called on const obj | ||
+ | |||
+ | const MyClass& ref = myObj; | ||
+ | ref.MyFunc(); // GET FUKT M8!! | ||
+ | ref.MyConstFunc(); // fine, const func called on const ref to obj | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Videos == | ||
+ | * <code>const</code> and const-correctness are introduced primarily in this video: [[Beginner C++ Game Programming Tutorial 11]] | ||
+ | * There is also a brief mention of <code>const</code> for variables in this video: [[Beginner C++ Game Programming Tutorial 2]] | ||
+ | |||
+ | == External References == | ||
+ | * [https://stackoverflow.com/questions/136880/sell-me-on-const-correctness Stack Overflow page describing the benefits of const-correctness] | ||
+ | * [https://isocpp.org/wiki/faq/const-correctness Definitive FAQ article on const-correctness] | ||
+ | * [http://en.cppreference.com/w/cpp/language/cv Advanced reference on const and related modifiers for types] | ||
+ | |||
+ | == See Also == | ||
+ | * [[Beginner C++ Game Programming Series#Topics Covered|List of topics covered in Beginner C++]] |
Latest revision as of 14:46, 12 September 2017
const
is a keyword that is applied to variables, references, and functions. It's basically like entering into a contract with the compiler that says "Shit's not gonna change yo!". A lot of scrub-level devs overlook this feature, but it is the shit and will make your code almost as rock SOLID as Chili's Johnson.
Contents
Why const
?
You often have variables where you store the result of some calculation, for example, but you don't ever have to modify the variable during its lifetime. Mark that shit as const
! That way, the compiler will tell you if you fuck up and accidentally write some code that would modify the variable. Take this code:
void foo( const int defcon )
{
if( defcon = 1 ) //< FLAGGED AS COMPILER ERROR! WORLD SAVED!
{
fire_missiles();
}
}
Without the const
, the operation would store the value 1 in the variable defcon
, then the value of defcon would convert to the boolean value true
, and the world would be fucked! This is just a simple example; proper use of const
can solidify your code in many ways. This is called 'const-correctness'.
Use Situations
There are a number of different situations where you can use const
, and the meaning of the keyword changes somewhat depending on the situation.
Variables
You can declare a variable as const
with the following syntax.
const int x = 69;
When a variable is declared in this manner, operations that modify the variable will cause a compiler error. It will also be impossible to pass a pointer or reference of that variable, unless the pointer or reference is also const
. Note that you must assign a const variable a value upon creation, since it will not be possible to assign one afterwards.
References
You can declare a const reference as follows:
const int& x_ref = x;
This is especially useful in function parameters, where we want to pass an object by reference (we don't wanna copy the whole damn thing!), but we aren't going to be modifying it:
void DoSomeShit( const MyObjectType& obj );
Declaring a reference parameter like this prevents code in the function body from modifying the object, and it also enables us to pass const
objects to this function (if the reference were not const, we would not be allowed to pass in const
objects).
Pointers
Much like references, you can declare const pointers that are not allowed to modify their targets.
const int* px = &x;
void DoSomeShit( const MyObjectType* obj );
We sometimes call these 'pointer-to-const' because it is the object that they point to that is not modifiable. There is another kind of const
pointer, defined like this:
int* const px = &x;
This kind of const
pointer is not retargettable. So here it is the pointer itself that is being locked down. You can also have both!
const int* const px = &x;
This pointer cannot be retargetted, and it cannot modify its target.
Member Functions
Member functions can also be declared as const. You might think that makes no goddamn sense, a function doesn't store anything--it can't be modified! But here the meaning is a bit different.
void MyMemberFunc() const;
When you make a member function const
, what you're saying is "this function will not modify the object on which it is called". This gives you two benefits: first of all, the compiler will tell you if you unintentionally do something that could modify the object inside of the function, and secondly, it allows you to call that member function even on objects that are const
!
class MyClass
{
public:
void MyConstFunc() const;
void MyFunc();
};
MyClass myObj;
myObj.MyFunc(); // fine
myObj.MyConstFunc(); // fine
const MyClass myObj_const;
myObj_const.MyFunc(); // GET FUKT M8!!
myObj_const.MyConstFunc(); // fine, const func called on const obj
const MyClass& ref = myObj;
ref.MyFunc(); // GET FUKT M8!!
ref.MyConstFunc(); // fine, const func called on const ref to obj
Videos
-
const
and const-correctness are introduced primarily in this video: Beginner C++ Game Programming Tutorial 11 - There is also a brief mention of
const
for variables in this video: Beginner C++ Game Programming Tutorial 2
External References
- Stack Overflow page describing the benefits of const-correctness
- Definitive FAQ article on const-correctness
- Advanced reference on const and related modifiers for types