I have some values such as width, height among some other that I set in the constructor at this moment. They are not currently constants but I want them to be that so I will change them now.
But I heard that it is not common to make such variables private const without also doing private static const. Is this the case? Or is it valid in this case? I also need centerWidth, which will be set by dividing the width variable by 2. Can I do this if I make them constants?
Are these values specific to the instance of the object, but only set in the constructor? Then static does not make sense, as every object would have the same height and width.
If you make a private data member const, the default assignment operator won't work and you will need to provide one.
But I heard that it is not common to make such variables private const without also doing private static const.
That's a useless generalisation.
Will the values differ between instances?
Yes: make them instance members;
No: make them static members.
That's all there is to it!
I also need centerWidth, which will be set by dividing the width variable by 2. Can I do this if I make them constants?
Yes, but consider doing this with an accessor function instead.
double T::centerWidth() {
return this->width / 2;
}
I have some values such as width, height among some other that I set in the constructor at this >moment. They are not currently constants but I want them to be that so I will change them now.
But I heard that it is not common to make such variables private const without also doing private >static const. Is this the case?
So, the way I would do this usually if you actually want them to be constant is as follows:
// Header
class Widget
{
public:
Widget();
~Widget();
// rest of your functions/variables
private:
static const int width;
static const int height;
// rest of your functions/variables
}
// Implementation
const int Widget::width = 640;
const int Widget::height = 800;
Widget::Widget()
{
// do some construction work
}
// ... rest of your definitions
Or is it valid in this case?
It's valid if the members you declare static will be the same for each object instance of the class you create.
I also need centerWidth, which will be set by dividing the width variable by 2. Can I do this if I >make them constants?
Yes, you can use a variable declared const in operations as normal:
const int a = 2;
int b = 2;
int c = a + b; // 4
If you are not going to change these variables by member functions then you do should declare them const and initialize in constructor initialization list.
class A
{
public:
A(int w) : width(w)
{
}
private:
const int width;
};
int main()
{
A(10);
return 0;
}
Since you set your variables in the constructor, they are instance specific, so static does not make any sense.
I know what problem you are trying to solve. You are trying to provide users read-only access to the width and height of an image, while allowing modifications from the class. You can not do that by declaring member variables const. All modification, including copy construction and assignment needs them to be non-const.
One solution is to use a public getter and a protected/private setter. In my own class I use the public member functions called xs() and ys() to return xsize and ysize respectively.
DO NOT EVEN THINK about declaring variables public const and using const_cast tricks to copy and assign, unless you like subtle, deep, pervasive bugs arising from improper compiler optimization and undefined behavior of const_cast.
Related
We know that const object members cannot be modified once declared but what is the real use of them? We can individually declare variables to be const inside the class or declare them private.
If there is any other significance of const object in C++, then please mention that too.
To answer your question literally:
If you make members of a class const, that applies to every instance of the class, but only to the members that you made const.
If you make an object const, that applies to a single instance of that class, but it does apply to all members of that instance.
const is one of the most elementary subjects in C++, in my opinion. Something that is way too often overlooked.
Generally const has three use cases:
Allowing the compiler to optimize more aggressively
Allowing the compiler to point out our mistakes when we accidentally try to change a const value
Convey intend by specifying that we do not want an object changed
In the case of a const member of a class, we force the object to be initialized during instantiation of the class. Preventing us from accidentally changing it's value in member functions. Which is the big difference to just using a private member variable. We still can accidentally change a private member variable anywhere inside the class.
One of the most useful ways to use const is with parameters:
This can allow major optimization for the compiler, for various reasons that are out of scope of this answer.
And in the case of const references, the compiler can prevent you from accidentally changing the value of that reference.
Most importantly, it allows you to define the signature of your function in a more clarifying way.
I luckily use this once(so far). And i never thought i would need to use a const in a member variable.
class TypeA {
protected:
DataX const* m_data; //get a pointer to a data that shouldn't be modified even inside the class.
public:
TypeA(DataX const* p){
m_data = p;
}
auto& getData(){ return *m_data; } //will return DataX const&
}
For the private member variables, i think they are best for helper-variables in the current class that are really not part of the object logically. Maybe for caching, temporary holder of some data that should be there for a time duration, a counter for an algorithm, etc. And they are only used and should be used in the current class. You don't want other programmers to use them in the derived class because they have a very special use so you hide them in private.
Another example for const member are for constant values aside for enums. I prefer enum over a variable that takes storage but some programmer prefer following on what they used to however you convinced them not to(maybe i'm wrong, and they are really correct, and maybe in the future for some reason the const in the language changed, and then using const might be better.)
class TypeA {
public:
const int HEY_VALUE = 101;
const int YOH_VALUE = 102;
const int HELP_VALUE = 911;
const float MIN_SOMETHING = 0.01;
static const int HELLO_EARTH = 10;
//...
}
I can't find this specific code of mine, but i think i used & instead of const*. I used it like this.
class TypeA {
protected:
DataX& m_data;
public:
TypeA(DataX& p):m_data(p){ //you can only set this once in the constructor
}
auto& getData(){ return m_data; } //will return DataX const&
}
I really prefer using . instead of -> for personal reasons so I really pushing myself to achieve the syntax i want and i came with these weird solutions. It's fun because I discovered that those weird approaches are still valid and achievable in c++.
Update
If there is any other significance of const object in C++, then please mention that too.
Maybe you can const some filler bytes on specific part of the class.
class TypeA {
protected:
const int HEADER_BYTES = 0x00616263;
int m_data1;
int m_data2;
const uint8_t ANOTHER_FILLER_FOR_SOME_REASON = 0xffffffff; //maybe forcing offset address, or alignment, etc.
int m_anotherData;
}
Generally, const keyword is being used to improve readability of the code you are writing.
However, in some cases const can also allow compiler optimizations. Let's see the following code snippet:
int const i = 1;
fun(&i);
printf("%d\n", i);
Here, trying to modify the variable i would cause an Undefined Behaviour. Therefore, the compiler will assume modification won't be even tried so it will pass the value 1 to the printf function.
Same is valid for const data members.
Well, I know the functionality of const data member in a C++ class.
What I want to know is, the purpose of introducing a const data member in a class. Why someone will use that while writing a real software? What are the real-life usage of const data members?
Please give me a few real life examples with reasons.
EDIT :
I am not asking about static const data member.
I am asking for some real life use cases where each object will be having a different const value for same data.
You'd use a const data member for the same reason that you'd use any const object: for a value that may be arbitrarily initialised but then never changed.
A good rule of thumb is to denote something as const "by default", so you can picture plenty of reasons to use it in a class.
class User
{
User(const std::string& name)
: name(name)
{}
private:
/**
* User's name is an invariant for the lifetime of this object.
*/
const std::string name;
};
Can you leave out the const here? Yeah, sure. But then you may accidentally change name when you didn't mean to. The entire purpose of const is to protect against such accidents.
However, sadly, your class will not be assignable!
There are several cases. The most obvious one is a static const data member. These are used as scoped constants:
class Something {
static const int SOME_CONSTANT = 17;
};
Note that under C++11 and onward, constexpr usually makes more sense in those cases.
This defines a constant that is typed and scoped to the class' implementation. I suspect this was not what you were asking, however.
The more interesting use case is for values that are different between instances of the class, but constant across the class' lifetime.
For example, suppose you have a RAID implementation, where a configuration sets the stripe width. You do not know the stripe width at compile time, so the above construct will not help you. You do want the width to remain constant throughout the class' lifetime however (maybe your code doesn't know how to handle stripe width changes).
In those cases, marking the value const, and setting it in the constructor, can give you compile time guarantee that no one is changing this value.
You use it exactly the same as you would use a globally declared const, only you want it to only apply to the class you have defined it in. For example
class Character
{
public:
Character()
:
mCurrentHealth{TOTAL_HEALTH},
mCurrentMana{TOTAL_MANA}
{
}
// Define lose/gain health/mana functions
// for mCurrentHealth and mCurrentMana
private:
int mCurrentHealth;
int mCurrentMana;
// Constants
const int TOTAL_HEALTH = 100;
const int TOTAL_MANA = 50;
};
There are many other examples, but the main point is that we don't want TOTAL_HEALTH and TOTAL_MANA defined outside the class, because they won't be relevant.
I was looking for a method to initialize a static float inside a structure BUT using the constructor of the struct. In this site there are already solution to initialize the value but I was unable to find a solution that explicitly use the constructor.
The idea is the following:
struct test {
static const float a;
int b;
test(int bb, float a);
};
test::test(int bb, float aa) {
b=bb;
a=aa;
}
int main() {
int bval=2;
float aval=0.25;
struct test aaa(bval, aval);
return 0;
}
How to implement it correctly? Thank you for any advice.
You can't initialise it other than
const float test::a = something;
Outside the class (in a single compilation unit). However, you can do what you wrote and that will set the variable to the value you pass.
If you're wanting to set it only on the first time the constructor is entered, you can (but shouldn't) do something like
test::test(int bb, float aa){
static float _unused = (test::a = aa);
b=bb;
}
But that doesn't initialise it, it just assigns a value to it, and you'll still have to pass the variable to the constructor every time and nothing will be done with it (unless you give it a default value or something). That is a really terrible design though, it's probably better just to have a static function in the class to set the variable.
Static members are not associated with a particular instance, so they will only ever be initialised once. Constructors on the other hand are invoked on a per-instance basis, so it doesn't make sense to do what you're trying to do.
You can, on the other hand, assign a new value to static members in a constructor, as you're doing above, but you still have to actually initialise the static member outside the struct in the normal manner beforehand.
It's worth observing in passing that other languages (e.g. Java) have the concept of a static constructor for exactly this sort of thing - but C++ doesn't.
That said, you might find the following question interesting:
static constructors in C++? I need to initialize private static objects
You can't initialize a static const var inside constructor.
You should initialize at declaration
static const float a = 3.1416f;
Ensure you understand const keyword.
And should be integral.
Hi I was trying to define a constant inside a class, doing it the normal or usual way doesnt seem to work
class cat
{
public:
cat();
~cat();
private:
static const int MAX_VALUE = -99999;
int Number;
public:
void OrganizeNumbers();
void SetNumbers();
};
So the solution I found after doing some research was to declare it as static but what does this means and also I want to ask it is really necesary to declare a constant, becuase as you can see it is private right? i means it can only be accessed by the class methods so why to set a constant and also I read that using static only allows you to use integral type so its actually a dissavantage... if you are thinking to make a game.
static means that the member will be shared across all instances of your object.
If you'd like to be able to have different values of a const member in different instances you'll need to use a initialization list to set it's value inside your constructor.
See the following example:
#include <string>
struct Person {
Person (std::string const& n)
: name (n)
{
// doing: 'name = n' here is invalid
}
std::string const name;
};
int main (int argc, char *argv[]) {
Person a ("Santa Claus");
Person b ("Bunny the Rabbit");
}
Further reading
[10] Constructors - parashift.com/cpp-faq
10.1 Construct Initialization List
Initialization Lists in C++
1) Declare it "private" if you're only going to use MAX_VALUE inside your class's implementation, declare it under "public" if it's part of your class's interface.
2) Back in "C" days, "static" was used to "hide" a variable from external modules.
There's no longer any need to do this under C++.
The only reason to use "static" in C++ is to make the member class-wide (instead of per-object instance). That's not the case here - you don't need "static".
3) The "const" should be sufficient for you.
4) An (older-fashioned) alternative is to define a C++ enum (instead of a "const int")
There seems to be some confusion of ideas here:
A static member doesn't have to be an integral type, the disadvantage you mention does not exist.
const and private are unrelated, just because a member can only be accessed from instances of a given class, doesn't mean that nothing is going to change it.
Being const-correct guards against runtime errors that may be caused by a value changing unexpectedly.
you have to init the const attribute in the constructor with :
cat() : MAX_VALUE(-99999) {}
(which was declare as const int MAX_VALUE;)
I'm really new to C++ and one of the first things that has me really stumped is how to write a getter/setter that can use dot notation to get at a property.
For instance, instead of:
myObj.getAlpha();
it would be
myObj.alpha;
Is using dot notation like this frowned upon in C++ or is it just a pain to setup? I've had a hard time tracking down examples that weren't totally over my head so any guidance is much appreciated!
You can actually implement a getter and setter to a field like
myObj.alpha
but that is hard to setup and requires a proxy class.
The way for doing this is:
template<typename T>
class SetterProxy
{
T *m_T;
public:
SetterProxy(T &property) : m_T(&property) { }
SetterProxy(const SetterProxy&) = delete;
SetterProxy operator =(const SetterProxy&) = delete;
operator T&()
{
return *m_T;
}
T &operator =(T &other)
{
*m_T = other;
return *m_T;
}
}
class MyClass
{
int m_alpha;
public:
SetterProxy<int> alpha;
MyClass() : alpha(m_alpha) { }
}
"Properties" in other programming languages are mostly a quick shorthand - a superficial shorthand for a pair of function calls. The other benefits (like metadata) don't really exist in C++. You have the following options:
Make your own "properties". In other words, a getProperty() and setProperty() pair of functions.
Expose a member variable as public. If you only want to expose a "getter", expose a public const reference to a member variable.
As others are saying, write a class which you expose as a public member function, but handles the getting / setting so you can "intercept" it. This is, imo, way too much effort for whatever benefit it can provide.
I would suggest going with the simplest option for you, without giving up type safety & encapsulation. As long as the compiler still prevents external classes from messing things up in your class, public member variables are fine.
Consider accessing the property using the proposed notation.
alpha is obviously a member of the class, let's say of type member_t. Let's also say that the property you intend to add is of type prop_t. Now if member_t is the same as prop_t you haven't really made a property because you have provided free access to the underlying member, so let's assume that member_t is different from prop_t.
It then follows that member_t must have an implicit conversion to prop_t (which is doable, but usually frowned upon).
It also means that member_t must override the assignment operator to store the value provided to it when you set it.
Finally, you have to add getter and setter methods to the class which implement the get/set logic, and have member_t aggregate pointers to these functions as members (so that it can call the getter inside the implicit conversion to prop_t and call the setter inside the overridden assignment operator).
All of the above is certainly doable, but why would you want to write all this code? There is no tangible benefit at all, and doing it just for the sake of making C++ look like a language it is not won't earn you much support.
The easiest way is to have alpha as just an accessible (probably public) attribute of the class, or a variable!
class Obj
{
public:
char alpha;
Obj()
:alpha('a')
{
}
};
int main()
{
Obj myObj;
char letter = myObj.alpha;
// [...]
}
C++ doesn't have the "properties" that you are looking for.
If alpha is a public property of the class - you can do that. Nothing special to write for that, its built in.
You would use getters/setters for protected/private properties, because they're not directly accessible from outside (because, well, they're protected/private).
(by property I mean a class data member/variable, that's how its called in C++ usually).
You could declare your member variables public, then you don't need a function to access them. However this is normally not good practice.
Personally, I strongly agree with get\set accessors - others may argue otherwise, and they are entitled to their own opinion.
With C++, there is no official way to create a property, however there are some compiler-specific methods that you can use to expose properties as you would in, for example, C#.
With Microsoft Visual C++, you can use the properties as is described here: http://msdn.microsoft.com/en-us/library/yhfk0thd%28v=vs.80%29.aspx and I'm sure there are other methods of performing the same task on other compilers. Most of my code is written on and for the windows platform so I can exercise this luxury, if you are planning on working with a different compiler, you should avoid using this for obvious reasons.
There may be some sort of BOOST implementation that allows you to do it more safely, but don't quote me on that. - I know boost can do some pretty cool things though.
As to why people use getters and setters, well. To start, directly accessing an object's data sounds messy, but it also removes a lot of flexibility.
Consider with get\set accessors you can:
-More easily detect what is accessing your objects data
-Implement 'virtual variables' or rather, variables that contain data that must be generated per call.
-Redesign your object and possibly remove\redesign variables without having to worry about backwards compatibility
-Override the get\set accessors or implement them form an inherited interface.
I'm probably missing a couple reasons as well.
I posted on the my Italian blog a post where I explain a way to emulate the property construct of the CBuilder in the C++ standard. Just as reference here I report a class declaration called CPanel using the CBuilder syntax for property definition:
class CPanel
{
private:
int m_Width; // Private member for Width property
int m_Height; // Private member for Height property
protected:
void __fastcall SetWidth(int AValue); // Set the Width property
int __fastcall GetWidth(); // Get the Width property
void __fastcall SetHeight(int AValue);// Set the Height property
int __fastcall GetHeight(); // Get the Height property
public:
CPanel()
{
}
__property int Width = {read=GetWidth, write=SetWidth};
__property int Height = {read=GetHeight, write=SetHeight};
}
As you see the the syntax is very simple, you can define the private members m_Height and m_Width, the protected setter and getter methods and finally you can define your properties using the special keyword called __property. The following code shows you how to use the properties in your main function:
int main()
{
CPanel Panel;
Panel.Width = 10;
Panel.Height = 10;
int TmpWidth = Panel.Width;
int TmpHeight = Panel.Height;
}
We can emulate the same syntax defining a template class for our generic property, the following code shows a definition of a template class for this purpose:
template<typename owner_t,
typename prop_t,
void (owner_t::*setter)(prop_t),
prop_t (owner_t::*getter)()>
class CProperty
{
public:
// Constructor
CProperty(owner_t* owner){m_owner = owner;}
// op = overloading
void operator=(prop_t value)
{
return (m_owner->*setter)(value);
}
// op type overloading
operator prop_t()
{
return (m_owner->*getter)();
}
private:
prop_t* m_owner;
}
Thanks the above template we can redefine our CPanel class using the standard c++ language:
class CPanel
{
private:
int m_Width; // Private member for Width property
int m_Height; // Private member for Height property
protected:
void SetWidth(int AValue); // Set the Width property
int GetWidth(); // Get the Width property
void SetHeight(int AValue);// Set the Height property
int GetHeight(); // Get the Height property
public:
CPanel()
:Width(this), Height(this)
{
}
CProperty<CPanel, int, SetWidth, GetWidth> Width;
CProperty<CPanel, int, SetHeight, GetHeight> Height;
}
As you can see the syntax is very similar, but now it is standard. You can use the new CPanel class like previous main function:
int main()
{
CPanel Panel;
Panel.Width = 10;
Panel.Height = 10;
int TmpWidth = Panel.Width;
int TmpHeight = Panel.Height;
}
Here is a link to the full post (in Italian language)
I believe you are coming from objective C?
In C++, getters and setters are just methods, and functions invokation always requires ().
You can make the property public, and use myObj.alpha to access it, although what you want is direct access, not a getter method.