My C++ project is getting huge. In some situations I'm passing arguments by reference just for my own convenience, in some I don't. Here's an example:
struct foo{
foo(int &member){
this->member = &member;
}
private:
int *member;
};
I'm using this pattern when I don't want to create two instances of the int variable. I don't have to implement the get or modify methods to manipulate its value. Instead I can change the variable without even accessing the foo object. However sometimes I'm using a different way of managing the member variables:
struct foo{
foo(int member){
this->member = member;
}
void modify_member(){
this->member = 6;
}
int get_member(){
return this->member;
}
private:
int member;
};
I'm not sure whether mixing these two methods of managing members in the same struct is a good practice. Should I normalize it? So for example EVERY function in the given struct will be using the "pass by value" method?
Your first case is a recipe for disaster. You'll end up with dangling pointers and a truck load of undefined behaviour.
Your second case is a poor attempt at encapsulation. There's no need for it. Just use the int. That will reduce the size of your code base.
Code should be simple to read and simple to change, that is in a way that does not break your program. Example one will lead to code, where you can hardly tell where foo instances are altered. Not to forget all the others issues mentioned already.
Example two is okay. In general, providing getters and setters let you add constraints later such as checking value ranges. So I recommend using them, unless you have good reasons not to do so. It also makes refactoring easier.
When passing parameters in a function: As a rule of thumb use pass by value in case of primitive types: int, double, etc.. When passing objects use constant References foo(const MyClass &myClass).
class MyClass {
public:
MyClass(const MyOtherClass &member1, int member2){
this->member1 = member1;
this->member1 = member1;
}
// other functions, getters, setters omitted...
private:
MyOtherClass member1;
int member2;
};
Related
Say I have:
struct foo{
int bar;
int baz;
...
bool flag;
}
Can an access operator -> or . be overridden to detect if bar or any other member variable is modified ?
EDIT:
The purpose is if I have many member variables and any of them is changed, I have a quick way of setting a flag, instead of using setters to encapsulate all the variables, making the code verbose.
Your approach is flawed because even if you override access operators you will not catch pointers writing the actual memory.
If most of the variables have the same type you can use an enum for flags and a single function to set or get a specific variable.
For example:
private:
int bar;
int baz;
public:
enum IntVariables { varBar, varBaz };
bool flag;
void setVariable(int varId, int value) {
flag = true;
if (varId == varBar)
bar = value;
else if (varId == varBaz)
baz = value;
}
I considered the following approach:
Just use a wrapper class that can have any data type, but implement all operations. In this same wrapper class override operators, and use the wrapper class in other class that require any modifications of member variables to be detected.
template <class T>
class wrapper {
private:
T var;
... .. ...
public:
T doSomethingToVar(T arg);
... .. ...
//Wherever the variable is modified send out a notification to whomever needs to detect the changes.
};
Pros:
When declaring variables in whichever class needs to detect modification of variables, it is easy to declare using the wrapper, without much additional code.
To ensure modifications are detected, need to implement functions / getters / setters / overload operators to detect modifications. This is tricky, and requires some thought.
Cons:
Tricky to implement a general purpose wrapper that can detect all modifications, since complex types can have functions that modify themselves in ways one is not aware of.
Notes:
How to ensure that every method of a class calls some other method first?
This answer is a work in progress, and I think it may be useful to others and maybe just cool to know about eventually, so open to comments. Will keep updating.
Update:
While writing out the above answer, I considered a different approach, of shifting responsibility onto the member variable classes:
class DetectChanges{
void onDetectChanges(){
//This function should be called by all implementing classes when the class has changes.
}
Can make it a design choice that all member variables inherit from DetectChanges.
The above two approaches are what I'm considering now. Not a solution yet, but thought I would put it out for comments and see if eventually we can figure something out.
}
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.
I'm a Java developer trying to pick up C++. Is it okay to use a setter inside a constructor in order to reuse the sanity checks the setter provides?
For example:
#include <stdexcept>
using namespace std;
class Test {
private:
int foo;
void setFoo(int foo) {
if (foo < 42) {
throw invalid_argument{"Foo < 42."};
}
this->foo = foo;
}
public:
Test(int foo) {
setFoo(foo);
};
};
Yes, it is recommended to do this, basically for the reason you already mentioned.
On the other hand you should ask yourself if you need the setter at all and not directly implement the checks inside the constructor. The reason I am writing this is that setters in general result in mutable state which has many disadvantages as opposed to immutable classes. However sometimes they are required.
Another recommendation: If your class variable is an object and you can modify the constructor of this object, you could put the check into the constructor of this object:
class MyFoo {
public:
MyFoo(int value) {
if (value < 42) {
throw invalid_argument{"Foo < 42."};
}
v = value;
}
private:
int v;
}
This will enable you to use an initialization list in the constructor of your Test class:
Test(int foo) : foo(foo) {}
However, now the check is a property of the class of the variable and no longer one of the owning class.
Yes you can. It's fine as long as your setters are not virtual, because it's inheritance hierarchy in calling right functions as the "this" ptr is not ready yet.
Here is Herb Sutter GOTW on this matter: http://www.gotw.ca/gotw/066.htm
Yes, that's fine as long as it makes sense to have a setter for a particular member variable (have some logic that can't be checked by assignment only for example) . In this example, setFoo could've just taken an unsigned int and the caller would know not to pass negative values. Which in turn could eliminate the check and thus the need for a setter. For more elaborate checks, a setter and usage of that setter in the constructor is just fine.
Short answer: Yes. In fact, your example works.
Long answer: But it is not a good practice. Al least, you have to take care.
In general, a set function works with a constructed object. It is supposed that the invariant of the class holds. The functions in a class are implemented considering the invariant is true.
If you want other functions to be used in a constructor, you would have to write some code. For example, to create an empty object.
For example, if in your class you change setFoo in the future (let's say setFoo changes the member foo only it is larger) you example stop working.
This is okay.
The only situation you cannot call member function is when the base classes are not constructed yet.
can member functions be used to initialize member variables in an initialization list?
I know this doesn't fit your situation. Its just for the sake of completeness:
When you are simply settings member values (without checks like yours in setFoo) it is recommended to use initialization lists in the constructor. This prevents members being "initialized" 2 times: 1. with their default value, 2. with the value that you passed into the constructor.
class Test {
private:
int foo_;
public:
Test(int foo)
: foo_(foo)
{ };
};
The usual way of designing setters and getters for a class member is the following
class QNumber
{
public:
void setNumber(unsigned int xNumber){ this->mValue = xNumber; };
unsigned int getNumber(void) const { return this->mValue; };
private:
unsigned int mValue;
}
If the member is another class (e.g. QRational as opposed to unsigned int), then the getter would be better returning a reference, in terms of performance.
So the modified design would be
class QNumber
{
public:
const QRational & value(void) const { return mValue;} // getter
QRational & value(void) { return mValue;} // 'setter'
private:
QRational mValue;
}
My question is - isn't there something potentially wrong with the latter approach? I have not seen it much in other people's code and to me, it seems more elegant than set/get method.
Many thanks,
Daniel
The point of getters and setters is to separate the interface from the implementation. If you return a reference, it has to point somewhere in the implementation. Now if you change the implementation, you'll have to start returning by value instead.
Personally I prefer public nonstatic members when the need for anything else is unlikely. Reference-semantic getters and setters provide the worst of both worlds. (I am working on a proposal to improve them, though.)
In addition to Potatoswatter's answer, please note one more point.
You second design provokes usage in the following form:
QRational& r = number.value();
// or
const QRational& r = number.value();
thus the user retains the reference to your inner object. It will be somewhat more difficult to manage in case your number object can be destroyed or moved while r is still there. This does not even depend on whether the const or non-const method is used.
The first design does not expose such problems.
At least in my opinion, if that member acts like an unsigned int (e.g., allows assignment to/from an unsigned int), and you're really sure this class should support direct manipulation of that member (i.e., it should have a "getter" and "setter" at all), then you should at least make access to it clean, rather than requiring other code to be written around that implementation detail. To avoid that, you should define how the type of this object differs from a plain unsigned int, then implement that behavior in a class that defines that type properly and directly.
class QNumber { // bad name--looks like a Qt class name
unsigned int value;
public:
QNumber(unsigned int value = 0) : value(value) {}
QNumber &operator=(unsigned int val) { value = val; return *this; }
operator unsigned int() { return value; }
};
With this, client code can be readable--instead of ugliness like x.SetNumber(2); or x.SetNumber() = 2; you just use x = 2;. This also avoids all sorts of lifetime issues that arise when you let a client get a pointer or reference to the class' internals (which you should generally avoid).
I have a class:
class A
{
private:
ComplexClass member1;
public:
getMember1(){return member1;};
};
and I have an implementation that, for code simplification (more easily understandable), needs to retrieve that member1 to work with it. The first thing that would come to my mind would be:
ComplexClass *myComplexClass = &getMember1();
myComplexClass.getSomething();
myComplexClass.getSomethingElse();
etc.
which is obviously not correct since I'm retrieving a pointer from a new object and not from member1 (and gets a compiler warning).
My question is: what is the best design to do things like this? How do I keep encapsulation and yet facilitate the access of a members using a pointer to it? (I only want to read from member1, not to write on it).
Should I make a
ComplexClass *getPointerToMember1()
inside the class A?
A const reference will keep them from editing. In my opinion, it makes your intention clearer than a const pointer.
class A
{
private:
ComplexClass member1;
public:
const ComplexClass &getMember1(){return member1;};
};
You're returning the member by value which makes a copy of the ComplexClass member. Thus you aren't working on the actual member when you call the subsequent methods (and what the compiler is telling you).
I think the more idiomatic C++ approach that helps maintain encapsulation and reduces coupling is to create an algorithmic member:
A::doStuff()
{
member1.getSomething();
member1.getSomethignElse();
}
This way anyone that uses class A doesn't care that the implementation uses a ComplexClass but instead just knows that they can tell A to do some work and it will get done in the best possible way.
EDIT for comment: In that case, I would suggest creating methods in A that get the values from ComplexClass (again to hide your implementation). If that's not suitable, then you could return the implementation by const reference: const ComplexClass& getMember1() const { return member1; }