This question already has answers here:
Is there any reason to use this->
(16 answers)
Closed 7 years ago.
what is the difference between this:
int MyClass::getId() {
return this->id;
}
and this:
int MyClass::getId() {
return id;
}
in C++?
The first example limits the scope where the name "id" is looked up to members of class MyClass.
the second example does not.
This makes a difference if e.g. MyClass has no member "id", or if the current method has a local variable or parameter with the same name.
It depends on the context. Examples:
template <typename> struct X { int a; };
int b;
template <typename T> struct Foo : X<T> {
int f() {
return this->a; // OK
// return a; // Error
}
int g() {
// return this->b; // Error
return b; // OK
}
};
Assuming your class has a member variable named id, there is no difference. Even if you have a global id variable, the member variable always takes precedence.
Your next question is:
So why does exist the this keyword?
There are some situations you absolutely need it.
One example is you want a function returning a pointer/reference(*) to the object itself:
return *this; //reference
return this; //pointer
Other is you want to pass it as an argument to a function
some_function(*this); //reference(&) or value, depends on some_function signature
some_function(this); //pointer
It can also be used in this->id, just for legibility, just for the next person reading the code immediately know id is a constituent of the class instead of a global, having no functional advantage.
If you use a debugger, the this may be also an inspectable variable by it.
Related
This question already has answers here:
What does "expression must be a modifiable lvalue" mean?
(3 answers)
What are rvalues, lvalues, xvalues, glvalues, and prvalues?
(13 answers)
Closed 7 months ago.
I have a class called CircuitProfiler that has a public member function switchState. Below is the code for it:
void CircuitProfiler::switchState(int index)
{
if (profilingNode)
{
switch (index)
{
case 0:
node->getVoltage().isKnown = !node->getVoltage().isKnown;
break;
}
}
}
The code I am having trouble with is the line:
node->getVoltage().isKnown = !node->getVoltage().isKnown;
I am getting error that says "expression must be a modifiable lvalue". There is a red line under node.
node is a pointer to an instance of a Node class that I created. node a private data member of CircuitProfiler. It is declared in CircuitProfiler as Node* node;
Node has a private data member called voltage, and getVoltage is a public member function of Node that simply returns voltage. voltage is declared in Node as VariableValue<float> voltage; and the code for getVoltage is:
VariableValue<float> Node::getVoltage()
{
return voltage;
}
voltage is an instance of a simple struct called VariableValue, the code for which is below.
template <class T>
struct VariableValue {
T value;
bool isKnown;
};
So why am I getting the error "expression must be a modifiable value"? Let me know if I need to provide any more information.
You are essentially saying (MCVE):
struct S { int i; }; // S as VariableValue<float>
S f() { return S{}; } // f as getVoltage
f().i = 1; // i as isKnown
You return a temporary in getVoltage(), which does not bind to an lvalue argument of operator=().
Likely you wanted to return voltage by reference in getVoltage(), if you wanted to use it this way, i.e.,
VariableValue<float>& Node::getVoltage()
{
return voltage;
}
You might also define a const version of it.
This question already has answers here:
problem sorting using member function as comparator
(9 answers)
Closed 2 years ago.
Is there any way to declare the comp function here under the scope of the class declared like this.
class Solution {
public:
bool comp(vector<int> x, vector<int> y){
return x[0] < y[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),comp);
return {{}};
}
};
This code snippet gives error :
reference to non static member must be called
The compiler would say that a non-static member reference must be relative to a specific object. This hint states that you must need to create an object before accessing the class members if the members ain't declared as static.
There are two options here:
Either Declare the class member function as static and then directly access.
OTOH, create an object (instance) of the class and then access the class member function.
The first's solution would look something like:
class Solution {
public:
// Declared as 'static', so you don't need to create any instances
static bool comp(vector<int> x, vector<int> y) {
// ...
}
};
// ...
Solution::comp(...);
And the second solution would be (perhaps you didn't want this one):
class Solution {
public:
bool comp(...) {
// ...
}
};
// ...
Solution s;
s.comp(...);
This question already has answers here:
Function pointer to member function
(8 answers)
Closed 4 years ago.
class Person;
class Command {
private:
Person * object;
//what is this? - a functor?...
void (Person::*method)();
public:
Command(Person *a, void(Person::*m() = 0): object(a),method(m) {}
void execute() { (object->*method(); }
};
// defining class Person here
class Person {
private:
string name;
Command cmd;
public:
Person(string a, Command c): name(a),cmd(c) {}
void talk();
void listen();
};
I was wondering what line 6 here means? Is that a way of defining a function or a functor? Also where does this type of function def appear and tends to be used? I found this example Under "Design Patterns" within Object Oriented Programming - this approach type is called Behavioural Command Pattern.
This is a pointer to Person class member taking no parameters and returning void.
Such initialization allows class Command referring to custom methods of class Person. Imagine class Person to be defined like this:
class Person
{
public:
void f1() { std::cout << "Call f1\n"; }
void f2() { std::cout << "Call f2\n"; }
};
Then we can create Command objects in this way:
Person p;
Command c1(&p, &Person::f1);
Command c2(&p, &Person::f2);
Executing these commands calls corresponding methods of given person:
c1.execute(); // prints "Call f1"
c2.execute(); // prints "Call f2"
This code line void (Person::*method)(); is a function pointer. void means that the function that is pointed won't return any data. (Person::*method)() is the definition of the pointer, the pointer will point to a void function.
In this page you can see how the syntax is:
Function Pointer Syntax
The syntax for declaring a function pointer
might seem messy at first, but in most cases it's really quite
straight-forward once you understand what's going on. Let's look at a
simple example:
void (*foo)(int);
In this example, foo is a pointer to a function taking one argument,
an integer, and that returns void. It's as if you're declaring a
function called "*foo", which takes an int and returns void; now, if
*foo is a function, then foo must be a pointer to a function. (Similarly, a declaration like int *x can be read as *x is an int, so
x must be a pointer to an int.)
The key to writing the declaration for a function pointer is that
you're just writing out the declaration of a function but with
(*func_name) where you'd normally just put func_name.
This question already has an answer here:
Why can in-class initializers only use = or {}? [duplicate]
(1 answer)
Closed 5 years ago.
I'm just going through the basic OOP concepts in C++ and came across the following:
class A{
public:
int i(20); //line 1
};
int main()
{
int j(20);
cout<<j<<endl;
A obj;
cout<<obj.i<<endl;
}
I get the following error at line1 when compiling (tried in both gcc and MSVC++),
expected identifier before numeric constant
I know how to assign default value for a non-static member (which can be done from C++11 on wards in different ways), but I couldn't get the reason why only this kind of default value initialization is not possible as doing the same initialization (for normal variables) anywhere else is valid.
What could be the reason for such restriction?
Edited:
From the links and answer provided, it is because "it might read as function declaration in some cases. Because of this ambiguity, it is not allowed."
But consider the following case:
//global scope
struct B{
int j;
};
int B = 10;
int object(B);
This is also a similar case, where int object(B) might be understood as a function object taking B object as argument and with int return type.
I tried this in gcc and MSVC++ and object is treated as an int variable. Why it is not restricted in this case?
Using parentheses was deemed to be too confusing since it would read very similarly to a function declaration. Think about the case of a default constructor:
class A{
public:
int i(); // function declaration -- did you mean to
// use the default constructor instead?
};
There are other ways to do it though:
class A{
public:
int i = 20;
int i{20};
int i = {20};
};
This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 5 years ago.
According to MSDN: "When following a member function's parameter list, the const keyword specifies that the function does not modify the object for which it is invoked."
Could someone clarify this a bit? Does it mean that the function cannot modify any of the object's members?
bool AnalogClockPlugin::isInitialized() const
{
return initialized;
}
It means that the method do not modify member variables (except for the members declared as mutable), so it can be called on constant instances of the class.
class A
{
public:
int foo() { return 42; }
int bar() const { return 42; }
};
void test(const A& a)
{
// Will fail
a.foo();
// Will work
a.bar();
}
Note also, that while the member function cannot modify member variables not marked as mutable, if the member variables are pointers, the member function may not be able to modify the pointer value (i.e. the address to which the pointer points to), but it can modify what the pointer points to (the actual memory region).
So for example:
class C
{
public:
void member() const
{
p = 0; // This is not allowed; you are modifying the member variable
// This is allowed; the member variable is still the same, but what it points to is different (and can be changed)
*p = 0;
}
private:
int *p;
};
The compiler won’t allow a const member function to change *this or to
invoke a non-const member function for this object
As answered by #delroth it means that the member function doesn't modify any memeber variable except those declared as mutable. You can see a good FAQ about const correctness in C++ here