C++ access constant value declared in cpp - c++

I have a main method in my main.cpp that I would like to display the value of a constant int I have declared.
I added a DeclareConstant class.
Here is my DelcareConstant.h
#pragma once
class DeclareConstant
{
public:
const int x;
Part1(void);
Part1(int x);
~Part1(void);
double getX(){return x;}
};
And source
#include "Part1.h"
Part1::Part1() : x(55){
}
How can I access X so I can display it in my main method? I need to check if I'm even initializing it correctly.

You can access x through getter function getX(), for example:
DeclareConstant dc;
std::cout << dc.getX() << std::endl;
Or
DeclareConstant dc;
std::cout << dc.x << std::endl;
However, you should define your getX like this:
class DeclareConstant
{
public:
int getX() const {return x;}
private:
const int x;
};
And please hide your class member.

If all your instances use the same constant value, you can make it static. This has a couple of advantages.
You can define it as below.
class Part1{
public:
static const int x = 42;
Part1(void);
Part1(int x);
~Part1(void);
double getX(){return x;}
};
and access it simply as Part1::x. You should make getX static as well, then you can do Part1::getX().
This will not work if each instance has its own const value.

You need an object or an instance of DeclareConstant to access the DeclareConstant's x member.
DeclareConstant myConst;
std::cout << myConst.x << std::endl; // Use x
But for your possible purpose and intentions you could make x as a static member.
class DeclareConstant {
public:
static const int x = 55;
// ...
}
You now don't need an instance to get the value of x:
std::cout << DeclareConstant::x << std::endl; // Use x

Related

callback in C++ struct

I have been trying to implement a callback function in c++. Within a class, I have a struct, a number of methods, and a method that creates an instance of the struct with one of the other methods as its argument.
The struct has many other variables, but an illustration is depicted here:
class MYCLASS
{
public:
MYCLASS();
struct TEST{
std::function<int(int)> foo;
};
int plus(int x){
return x + 1;
}
int minus(int x){
return x - 1;
}
void sim(){
TEST T; // make an instance of TEST
T.foo = plus(5); // assign TEST.foo a function (plus or minus)
T.foo(); // call the method we assigned
}
};
Within the sim method, I want to create an instance of test and give it either plus or minus, depending on some criterion. Both lines where I try and give the instance T a plus function and subsequently call it are incorrect.
If you want to delay the call to T.foo, then you could use a lambda like this:
T.foo = [this](int x) { return plus(x); };
T.foo(5);
Option - 1
If the member functions plus() and minus() are simple enough like you have shown, you can make them as lambda functions inside the struct TEST.
Since the capture-less lambdas can be stored in typed function pointers, the following will do what you want.
See live demo
#include <iostream>
class MYCLASS
{
int m_var = 5; // just for demonstration
public:
MYCLASS() = default;
struct TEST
{
using fPtrType = int(*)(int); // function pointer type
const fPtrType foo1 = [](int x) { return x + 1; }; // plus function
const fPtrType foo2 = [](int x) { return x - 1; }; // minus function
};
void sim()
{
TEST T;
std::cout << "Answer from int PLUS(int): " << T.foo1(m_var) << std::endl;
std::cout << "Answer from int MINUS(int): " << T.foo2(m_var) << std::endl;
}
};
Option - 2
If the above alter a lot in your code, use typed function pointer again for member functions and do as follows; which will avoid unnecessary copying(by capturing) the class instance to the lambda and template instantiation and other performance issues comes along with std::function as well.
See live demo
#include <iostream>
class MYCLASS
{
using fPtrType = int(MYCLASS::*)(int); // class member function pointer type
public:
MYCLASS() = default;
struct TEST { fPtrType foo = nullptr; };
int plus(int x) { return x + 1; }
int minus(int x) { return x - 1; }
void sim()
{
TEST T;
T.foo = &MYCLASS::plus; // now you can
std::cout << "Answer from int PLUS(int): " << (this->*T.MYCLASS::TEST::foo)(5) << std::endl;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ syntax would be a bit ugly
// later same ptr variable for minus()
T.foo = &MYCLASS::minus;
int answer = (this->*T.MYCLASS::TEST::foo)(5);
std::cout << "Answer from int MINUS(int): " << answer << std::endl;
}
};
int main()
{
MYCLASS obj;
obj.sim();
return 0;
}
Output:
Answer from int PLUS(int): 6
Answer from int MINUS(int): 4

Const member function of global variable modifying said variable via global function

The code below
#include <iostream>
class A
{
public:
int x;
double y;
A(int x_, double y_) : x(x_), y(y_)
{
}
void display(void) const;
};
class B
{
public:
static A staticObject;
};
void A::display(void) const
{
std::cout << x << ' ' << y << std::endl;
B::staticObject.x = 42;
B::staticObject.y = 3.5;
std::cout << x << ' ' << y << std::endl;
}
A B::staticObject(19, 29.3);
int main(void)
{
B::staticObject.display();
return 0;
}
prints out
19 29.3
42 3.5
and this makes me wonder:
Is it always safe to let a const member function modify the object it is called from via other means?
Further, is there any worst-case scenario that could be prevented if that member function (here display) were not declared as const?
Your code is valid and works, because display() is const but only with respect to its containing class, A. This has no impact on its ability to modify fields accessed another way--in your case via non-const public access to the two fields.
However, this code is terrible and scary.
what do you think as "safe"?
The only assumption you should make of a const member function is that it will not modify the current object it is in (this pointer). Constness though is not runtime enforced but during compilation time.
So when you "trick" your compiler with the help of static variables it cannot detect that you are actually accessing the same instance. The staticObject in B can also point to another A than the one it's being called from.
To be able to check it would require runtime checks which c++ does not do.

Mutable Variable in Class -- Issue

#include <iostream>
using std::cout;
class Test
{
public:
int x;
mutable int y;
Test()
{
x = 4; y = 10;
}
static void disp(int);
};
void Test::disp(int a)
{
y=a;
cout<<y;
}
int main()
{
const Test t1;
Test::disp(30);
t1.y = 20;
cout << t1.y;
return 0;
}
I am getting error with in the constructor:
void Test::disp(int a)
{
y=a;
cout<<y;
}
I don't understand why this is not working because y is mutable and its already updated successfully within constructor Test() but when its coming to disp(). its shows error..
I have also checked with some other examples also . So I came to know you can update a mutable variable once only. If you try to update it more then one time it shows an error. Can anyone explain why this happening or reason behind it?
Your problem doesn't have anything to do with mutable. You are trying to modify a non-static class member from a static method, which is not allowed. In your example it makes little sense to have the Test::disp method static in the first place.
You also seem to have misunderstood the meaning of mutable. It doesn't make members of a const object non-read-only. It makes it possible for const methods to write to members. Your code updated to show what mutable does:
#include <iostream>
using std::cout;
class Test
{
public:
int x;
mutable int y;
Test()
{
x = 4; y = 10;
}
void disp(int) const; // Notice the const
};
void Test::disp(int a) const
{
y=a; // ::disp can write to y because y is mutable
cout<<y;
}
int main()
{
Test t1;
t1.disp(30);
t1.y = 20;
cout << t1.y;
return 0;
}
And yes, there is no limit to the number of times a mutable variable can be written, just to be clear.

stopping a `const` member from being edited under another alias

I have a class with an const abstract member. Since it is abstract, the object must reside in a higher scope. However, it may be edited in this higher scope. I have made this MWE, and added comments explaining what I am trying to achieve (.i.e. I know this does NOT achieve what I want).
Besides commenting the hell out of it, what can be done to stop the user from editing the object. Preferably, an idiot proof method (optimally, compile error)
#include <iostream>
class Foo
{
private:
const int * p_abstract_const;
//int my application this is a pointer to abstract object
public:
Foo(const int * p_new_concrete_const)
{
p_abstract_const = p_new_concrete_const;
}
void printX()
{
std::cout << *p_abstract_const << std::endl;
}
};
int main()
{
int concrete_nonconst = 666;
Foo foo(&concrete_nonconst); // I want this NOT to compile
//const int concrete_const(1);
//Foo foo(&concrete_const); // only this should compile
foo.printX();
concrete_nonconst=999; // so that this will NOT be possible
foo.printX();
}
You can make your non-const int* constructor private without providing an implementation:
class Foo
{
private:
const int * p_abstract_const;
//int my application this is a pointer to abstract object
Foo(int * p_new_concrete_const);
public:
Foo(const int * p_new_concrete_const)
{
p_abstract_const = p_new_concrete_const;
}
void printX()
{
std::cout << *p_abstract_const << std::endl;
}
};
int main()
{
int concrete_nonconst = 666;
Foo foo(&concrete_nonconst); // This won't compile
const int concrete_const(1);
Foo foo(&concrete_const); // But this will
foo.printX();
concrete_nonconst=999; // so that this will NOT be possible
foo.printX();
}

Why is accessing private variable allowed here?

I have this class declared. I observed that in the method distance(Point b), how is it possible to access the private members of Point - b.x and b.y? If I try to access b.x and b.y in main, it is not allowed.
#include <iostream>
#include <cmath>
using namespace std;
class Point {
private:
int x, y;
public:
Point() {
cout << "Constructor called" << endl;
x = 0; y = 0;
}
~Point() {
}
void set(int a, int b) {
x = a;
y = b;
}
void offset(int dx, int dy) {
x += dx;
y += dy;
}
void print() {
cout << "(" << x << "," << y << ")" << endl;
}
// HERE
double distance(Point b) {
return (sqrt(pow(x-b.x, 2)+pow(y-b.y, 2)));
}
};
int main() {
Point p, q;
p.print();
p.offset(4, 3);
p.print();
q.set(10, 2);
cout << "Distance: " << p.distance(q) << endl;
return 0;
}
NOTE: I have compiled and ran the program on ideone.com
The concept of access specifiers such as private, public etc. applies to classes, not just objects of classes. If a variable is private in a class, and an object A of that class has a function that takes another object B of the same class, A has access to B's private members since A and B belong to the same class.
Copy constructors rely on this:
#include <iostream>
using namespace std;
class A {
public:
A(){val = 1.0;}
//copy constructor
A(const A& _other) {
val = _other.val; //accessing private member of _other
}
double dist(A _a) {return val - _a.val;} //accessing private member of _other
private:
double val;
};
int main() {
A a;
A b;
cout << a.dist(b) << endl;
}
int x, y; are private to the Class Point. It means all the members of Class Point can access,modify it.
The functions and constuctors of Class Point are public i.e Other functions(from some other class etc) [like main] can access them. The idea of OOPS is to keep your data safe, Anyone who wants to modify the values can do it via the public methods of that class. They can't access them directly. This allows you to keep any check for invalid modifications to data [setting invalid values like height = -4; etc]
If u keep int x,y as public [which is not correct OOPs] any function (main etc) can access it and modify the value to something undesirable.
Point p;
p.x = -5 (suppose you only wanted +ve values for x , you can't check if the functions accessing is setting some undesirable value)`
Not a relevant analogy , but still...You have a room in the house which only the family members can access. Any outsider who wishes to keep or remove or do anything to the things in the house has to ask your family members to do it. If u assume even family members are not allowed to access the room [assuming even member functions can't access variables ] then there is no use of keeping anythin in the room [the data cannot be used by anyone]