const object in c++ - c++

I have a question on constant objects. In the following program:
class const_check{
int a;
public:
const_check(int i);
void print() const;
void print2();
};
const_check::const_check(int i):a(i) {}
void const_check::print() const {
int a=19;
cout<<"The value in a is:"<<a;
}
void const_check::print2() {
int a=10;
cout<<"The value in a is:"<<a;
}
int main(){
const_check b(5);
const const_check c(6);
b.print2();
c.print();
}
void print() is a constant member function of the class const_check, so according to the definition of constants any attempt to change int a should result in an error, but the program works fine for me. I think I am having some confusion here, can anybody tell me why the compiler is not flagging it as an error?

By writing
int a = 19;
inside print(), you are declaring a new local variable a. This has nothing to do with the int a that you declared inside the class const_check. The member variable is said to be shadowed by the local variable. And it's perfectly okay to declare local variables in a const function and modify them; the constness only applies to the fields of the object.
Try writing
a = 19;
instead, and see an error appear.

You aren't changing the instance variable a you are creating a local variable a in each method.

You're not changing the member variable a in either print() or print2(). You're declaring a new local variable a which shadows the member variable a.

Also, unless I am mistaken, you forgot to actually declare the member variable const to begin with.

Related

C++ Member variable Initialized with non-zero value, but is zero in member function [duplicate]

While observing another person's code, I realized that within class A's method he declared a local int with the same name as a variable of class A. For example:
classA.h:
class A{
int Data;
void MethodA();
};
classA.cpp:
#include "classA.h"
using namespace std;
void A::MethodA(){
int Data; //local variable has same name as class attribute
Data = 4;
//Rest of Code
}
I found it weird that the compiler would accept this without returning an error. In the above case, would the 4 be assigned to the local Data or A::Data, and what problems could this cause in more complex situations?
The local variable will shadow the member one (it has the more narrow scope). If you just write
Data = 4;
you will assign to the local variable Data. You can still access the member variable with
this->Data = 4;
This works basically just as
{
int data = 4;
{
int data = 2;
data++; // affects only the inner one
}
}
As for problems in the future: As long as you and everyone who will ever work with your code understands the rules and is aware that you did this on purpose there is no problem. If you do not intend to do such things on purpose, make your compiler warn about it.
However, it would certainly be saver if you followed a naming scheme for member variables, e.g. append an underscore like
class A{
int Data_;
void MethodA();
};

Problems returning an object in C++

I'm just starting out in C++ and I'm having problems with one part of my assignment:
class Something {
public:
Random& random(); // should access a data member of type Random
private:
Random test(int r, int c);
}
Random& Something::random() {
return (Random&) test;
}
And now there's an error with "test" in the function definition of random(), because "the expression must be an lvalue" and I built the solution and the error message given says "'&' : illegal operation on bound member function expression "
I have to keep the function declaration the way it is, because it's listed that way in the specs.
How do I fix this?
You said in a comment: "test" is supposed to be a member variable.
Then, you need to change your class to:
class Something {
public:
Random& random(); // should access a data member of type Random
private:
// Not this. This declares test to be member function.
// Random test(int r, int c);
// Use this. This declares test to be member variable.
Random test;
}
Random& Something::random() {
return test;
}

c++ classes, const function that calls non constant function

in C++ classes, if I have a constant function (In my understanding constant functions are classes that cannot change anyting in the class, hope this is true)
for example a function like this
int output(int value) const
Am I allowed to call a function within this function remove that actually changes anything in the class?
For example lets say I have a variable called number in private.
my output function adds one to the variable number, but not directly, it calls
a non constant function called addOne which adds one to the variable number.
I notice that I am getting an error when a output function is calling addOne(I know that output function is const but it modifies a value, but it modifies it indirectly). I wonder why I am getting an error, what error compiler actually detects here?
Thank You, and sorry if my question is hard to understand.
Thank you all for answering.
The answer is simple - no, you cannot. Every class method is a function that implicitly passes this as a parameter. When you declare a method as const, that means that it will actually pass const this to this function. It is both correct logically and syntactically not to call not const methods from const methods.
const instances can only call const functions. Say:
class YourClass {
...
int output(int value) const;
int regularMethod(); // Non-const
...
};
is your class with a const function. And the variables:
const YourClass obj1;
YourClass obj2;
Here obj1 can call output method while it cant call regularMethod. obj2 can call both.
Every const function() is getting a const this pointer as a default parameter, so you cannot change a member variable of a class even if you try to call a non_cost function from a const function and try to modify a member variable.
So if you try to call a non const function from a const function, you will get compile error.
The answer is NO. The long answer is perhaps YES, provided you use an abomination like this, via const_cast-ing this in the const calling function (but you have to make sure you invoke your function on non-const objects, otherwise it leads to undefined behaviour):
#include <iostream>
struct Foo
{
int x = 0;
void f()
{
++x;
}
void modify_x() const
{
const_cast<Foo*>(this)->f(); // call non-const member function
}
};
int main()
{
Foo foo;
std::cout << foo.x << std::endl;
foo.modify_x();
std::cout << foo.x << std::endl;
}

Difference when assigning values to class data members using self pointer

Suppose I have a class like:
Class MyClass
{
int myVar1;
int myVar2;
void myMethod();
}
is there any difference in the two value assignments below ?
void MyClass::myMethod()
{
//VARIABLE ASSIGNMENT
myVar1 = 99;
//USING POINTER TO CLASS
this->myVar2 = 99;
}
What's the use of the
this->
pointer in variables' assignment (except other cases when eg. passing the class via a function etc.) ?
It's the same thing, unless you happen to have two variables with the same name in the scope. In that case you can differentiate using this->.
It makes a difference in the following situation:
void MyClass::myMethod(int myVar1)
{
myVar1 = 99; //doesn't change the member
this->myVar1 = 99; //changes the member
}
In your case, no difference.
There is no difference. Sometimes using this-> aids in disambiguation, but not here.

Illegal call to non-static member function (C++)?

I'm developing a game which is based around the user controlling a ball which moves between areas on the screen. The 'map' for the screen is defined in the file ThreeDCubeGame.cpp:
char m_acMapData[MAP_WIDTH][MAP_HEIGHT];
The ThreeDCubeGame.cpp handles most of the stuff to do with the map, but the player (and keyboard input) is controlled by ThreeDCubePlayer.cpp. When a player moves into a new map cell, the game will have to check the contents of that cell and act accordingly. This function in ThreeDCubeGame.cpp is what I am trying to use:
inline char GetMapEntry( int iMapX, int iMapY ) { return m_acMapData[iMapX][iMapY]; }
So, in order to check whether the player is allowed to move into a map cell I use this function call from ThreeDCubePlayer.cpp:
if (ThreeDCubeGame::GetMapEntry(m_iMapX+MAP_OFF_X, m_iMapY+MAP_OFF_Y) == ' ')
{
// do stuff
}
But, when I compile this, I get the warning "error C2352: 'ThreeDCubeGame::GetMapEntry' : illegal call of non-static member function". Is this something to do with the scope of the variables? Is it fixable without redesigning all the code?
class A {
int i;
public:
A(): i(0) {}
int get() const { return i; }
};
int main() {
A a;
a.get(); // works
A::get(); // error C2352
}
There's no object to call the function with.
GetMapEntry is not static so you can't call it without an object of the type ThreeDCubeGame.
Alternatives:
-Make GetMapEntry static: static inline char GetMapEntry
-Create an instance of ThreeDCubeGame and do instance.GetMapEntry(
ThreeDCubeGame is a class, not an instance, thus you can only use it to access static members (that is, member function with the keyword static)
You have to instantiate an object of this class to use non-static members
ThreeDCubeGame map;
...
map.GetMapEntry(iMapX, iMapY).
You are trying to call a class method. Is that what you intend? Or do you mean for GetMapEntry to be an instance method? If it's a class method, it needs to be marked static. If it's an instance method, you need to call it with an instance of ThreeDCubeGame. Also, is GetMapEntry even a member of a class?
The error indicates that your are calling the GetMapEntry function as a static one whereas you have declare it as a member function. You need to:
call it via an instance of ThreeDCubeGame: threedcubegameinstance.GetMapEntry(),
declare the GetMapEntry function as static (add a static before inline and make m_acMapData static too).
You're missing the "static" keyword.
// .h
class Playfield
{
public:
static char GetTile( int x, int y );
// static on a method means no 'this' is involved
};
// .cpp
static char tiles[10][10] = {};
// static on vars in .cpp prevents access from outside this .cpp
char Playfield::GetTile( int x, int y )
{
// handle invalid args
// return tile
return tiles[x][y];
}
There's other options if you want only one unique playfield:
You can make Playfield a singleton, turn it into a namespace or use global functions.
The result is the same from the caller's point of view.
On a side note:
Since all of these use a static and/or global variable it's inherently not thread-safe.
If you require multiple playfields and/or want to play safe with multi-threadding and/or want to absolutely do it in an OOP fashion, you will need an instance of Playfield to call the function on (the 'this' pointer):
class Playfield
{
public:
char GetTile( int x, int y ) const { return this->tiles[x][y]; }
// you can omit 'this->', but it's inherently present because
// the method is not marked as static
public:
Playfield()
{ /*you will have to initialize 'this->tiles' here because
you cannot use the struct initializer '= {}' on member vars*/ }
private:
char tiles[10][10];
};
The calling code would use Playfield like this:
void main()
{
// static version
char tile11 = Playfield::GetTile( 1, 1 );
// non-static version
Playfield myPlayfield;
char tile12 = myPlayfield.GetTile( 1, 2 );
}
It can be useful to have a class containing a collection of functions, without any data members, if you don't want to expose the helper-functions.
Otherwise it would be more practical to use a namespace to collect these functions in.
Example:
class Solvers
{
public:
void solve_a(std::vector<int> data);
void solve_b(std::vector<int> data, int value);
private:
int helper_a(int a, int b);
}
But a class needs to be initialised before use.
The simplest way to make these functions usable would be to mark them static in the class:
static void solve_a(std::vector<int> data);
Then the member-functions can be used as:
Solver::solve_a(my_vector);
Another way would be to initialise the class before using:
Solver solver;
solver.solve_a(my_vector);
And the third method, not mentioned before, is by default initialising it during use:
Solver().solve_a(my_vector);