How to make a function pointer constant - c++

A typical getter/setter looks like this:
void setName(const std::string& _name) { name = _name; }
std::string getName() const { return name; }
How can I do the same if the member is a function pointer like this:
void setBotFunc(int(*botFunc)()) { botFunction = botFunc; }
int (*getBotFunc() const)() { return botFunction; }
Particularly I don't know how to declare the setter in a way that says 'I will only read and not modify the pointer (value)'. Does this even make sense? const int (*botFunct)() is obviously treated like a function which returns a const int.

void setBotFunc( int(* const botFunc)() )
{
botFunction = botFunc;
}

Related

Why do I get this error "expression must be an lvalue or a function designator" for some of my data members?

I am trying to create a function that prints whatever I feed it from the class I created. I can only get some of my class object data members to work with my print function.
I have tried using pointers and references in some source codes I found online but they didn't work. After working on this problem for about a week now I feel like I have tried everything.
void print(string* object);
enum Degree { SECURITY = 1, NETWORKING = 2, SOFTWARE = 3};
class Student {
public:
Student(string ID, string first, string last, string Email, int Age, int days1, int days2, int days3, Degree StudentDegree) {
studentID = ID;
firstName = first;
lastName = last;
email = Email;
age = Age;
daysTillComplete[0] = { days1 };
daysTillComplete[1] = { days2 };
daysTillComplete[2] = { days3 };
studentDegree = StudentDegree;
return;
}
string getID() const;
void setID(string ID);
string getFirst() const;
void setFirst(string ID);
string getLast() const;
void setLast(string ID);
string getEmail() const;
void setEmail(string ID);
int getAge() const;
void setAge( int Age);
int getdays1();
int getdays2();
int getdays3();
void setDaysTilComplete(int days, int days1, int days2);
Degree getDegree() const;
void setDegree(Degree degreeType);
private:
string studentID = "No name";
string firstName = "No name";
string lastName = "No name";
string email = "No name";
int age = 7;
int daysTillComplete[3];
Degree studentDegree = NETWORKING;
};
void print(string* object) {
cout << *object << endl;
}
string Student::getID() const {
return studentID;
}
string Student::getFirst() const {
return firstName;
}
string Student::getLast() const {
return lastName;
}
string Student::getEmail() const {
return email;
}
int Student::getAge() const {
return age;
}
int Student::getdays1() {
return daysTillComplete[0];
}
int Student::getdays2() {
return daysTillComplete[1];
}
int Student::getdays3() {
return daysTillComplete[2];
}
Degree Student::getDegree() const {
return studentDegree;
}
void Student::setID(string ID) {
studentID = ID;
}
void Student::setFirst(string first) {
firstName = first;
}
void Student::setLast(string last) {
lastName = last;
}
void Student::setEmail(string Email) {
email = Email;
}
void Student::setAge(int studentAge) {
age = studentAge;
}
void Student::setDaysTilComplete(int days1, int days2, int days3) {
daysTillComplete[0] = days1;
daysTillComplete[1] = days2;
daysTillComplete[2] = days3;
}
void Student::setDegree(Degree degreeType) {
studentDegree = degreeType;
}
int main() {
Student vallery("A1", "Vallery", "Williams", "vallery.a.williams1234#gmail.com",21,52,28,32,NETWORKING);
print(&vallery.getID());
print(&vallery.getFirst());
print(&vallery.getLast());
print(&vallery.getEmail());
//print(&vallery.getAge()); <--- will not compile if this statement is in the program
//print(&vallery.getdays1()); <--- will not compile if this statement is in the program
////print(&vallery.getdays2()); <--- will not compile if this statement is in the program
////print(&vallery.getdays3()); <--- will not compile if this statement is in the program
//print(&vallery.getDegree()); <--- will not compile if this statement is in the program
cin.get();
return 0;
}
My expected results for example print(vallery.getFirst); would be print vallery. That works, but when I do print(vallery.getAge); it should be 21 but I can't even compile it because I get the "expression must be an l-value or function designator" error. Also using int instead of string for the data type of the print function doesn't work either. I must be using something incorrectly. Can someone point me in the right direction? After a bunch of research I haven't found any solutions.
There are several things are are probably going wrong with this code.
The most obvious is that your print function expects a string*. The calls that fail are those where you try and give the function something that is not a string*. For example, getAge() returns a int, where you are taking the address of the returned int. So you are trying to call print(int*) which then is failing. To solve this you can either using templating or have overloads. Here is a recommended template function:
template <typename T>
print (const T& _object)
{
cout << _object << endl;
}
A second problem, which is what is masking this first error comes from the fact you are taking a ptr instead of a reference (or a const reference as in my template function). If you want to print something, you want it to definitely be there and not a nullptr. So use references. In saying this, I think the ones that you say will work, definitely shouldn't work (even though they are string*'s) under any sane compiler. Perhaps the current error is hiding those errors.
The error “expression must be an lvalue or a function designator” comes from the fact that you are trying to take the address of an r-value. That is a value that is temporary and/or has not been bound to a name. Your getters return a copy of the value stored in your student object and this value has no address. You are trying to get the address of an addressless value, hence the error that it must be lvalue.
To solve this: Firstly don't use pointers, use a const reference. Secondly, have your getters return a const reference for objects. For example,
const string& Student::getID() const;
If your print function takes a const reference, it is able to handle a temporary variables for the cases where you return an int or other primitive type. Since your other getters return a reference to an addressable value, the print function can also take this reference without having to needlessly copy the values.

Use singleton classes in c++

I created a singleton class
class AreaDataRepository {
private:
AreaDataRepository();
AreaDataRepository(const AreaDataRepository& orig);
virtual ~AreaDataRepository();
Way onGoingWay;
public:
static AreaDataRepository& Instance()
{
static AreaDataRepository singleton;
return singleton;
}
void SetOnGoingWay(Way onGoingWay);
Way const & GetOnGoingWay() const;
};
void AreaDataRepository::SetOnGoingWay(Way onGoingWay) {
this->onGoingWay = onGoingWay;
}
Way const & AreaDataRepository::GetOnGoingWay() const {
return onGoingWay;
}
header file of Way
class Way {
private:
std::string id;
std::string name;
public:
Way();
Way(const Way& orig);
virtual ~Way();
void SetName(std::string name);
std::string const & GetName() const;
void SetId(std::string id);
std::string const & GetId() const;
};
Then i'm created a Way object and set vales of id and name.
Way wayNode;
wayNode.SetId("123");
wayNode.SetName("jan")
AreaDataRepository::Instance().SetOnGoingWay(wayNode);
After assign OngoingWay accessing it from another class.
std::cout << AreaDataRepository::Instance().GetOnGoingWay().GetId();
the vale is not printing.
I'm going psychic here.... and I divine that your implementation of SetId is like this:
void SetId(std::string id) { id = id; }
that does not set the member variable, that sets the parameter to itself. And since your constructor most likely set the member variable id to "" you're printing empty strings. Either change the name of the parameter (to newId for example) to avoid the conflict or change the implementation to:
void SetId(std::string id) { this->id = id; }
As proof of this claim here's the result for the first version, as you see it prints nothing. And here is the result for the second, as you can see it prints the number.
The problem boils down to this: you have function parameter names that are the same as the name of your member variables and the function parameters are shadowing/hiding the member variables.
The only place this cannot happen is in a constructor's initialization list:
class Foo {
int x;
public:
Foo(int x): x(x) {} // <-- this works
void SetX(int x) { x = x; } // <-- this won't the parameter is hiding the member variable
};
Demo for the above snippet
std::cout is buffered in most implementations, if not in all. That means, the stream will wait for you to end a line before writing out any data. So, you can easily fix this by changing your output statement to
std::cout << AreaDataRepository::Instance().GetOnGoingWay().GetId() << std::endl;

C++ getter/setter paradigm

I recently came across this class and was surprised at how the getters and
setters were implemented.
I have not come across this before and would welcome some second opinions.
Do you think this is a good paradigm?
Is is bad?
Is it evil?
Header:
class Tool
{
public:
Tool();
virtual ~Tool();
bool setName(const std::string &name);
bool getName(std::string &name) const;
void clearName();
private:
std::string m_name;
bool m_nameSet;
};
cpp file:
#include "Tool.h"
Tool::Tool()
: m_name("")
, m_nameSet(false)
{
}
Tool::~Tool()
{
}
bool Tool::setName(const std::string &name)
{
m_name = name;
m_nameSet = true;
return (m_nameSet);
}
bool Tool::getName(std::string &name) const
{
bool success = false;
if (m_nameSet)
{
name = m_name;
success = true;
}
return (success);
}
The way you selected for getter is not popular, programmers prefer to return data from getter
std::string getName() const;
Why an item that set before, or has an initial data, should be re-checked on getter? If you want validate the data, validate it on setter.
However if your insist to return a value as "is name set before", you can write a third method by means of bool isNameSet() const;
This looks a lot like C where it is usual to return status codes to see if a functions fails or not.
Then also there are better methods to verify that a name is set or not. One could be to use the boost::optional to me this is a better way to declare intent that the name might not be set at all times.
I would however wonder if it's not better to make sure the name is set at all times by only having one constructor that takes a std::string as a parameter.
class Tool
{
public:
//Constructor already does the right thing
Tool() = default;
virtual ~Tool();
//Use void or return the modified class, akin to operators
void setName(const std::string& name)
{
m_name = name;
}
//Alternatively
Tool& setName(const std::string &name)
{
m_name = name;
return *this;
}
//Return const reference to the value if possible, avoids copying if not needed
//This will fail at run time if name is not set
//Maybe throw an exception if that is preferred
const std::string& getName() const
{
return *m_name;
//Or
if(m_name) return *m_name;
else throw some_exception;
}
//Or return the optional, then calling code can check if name where set or not
const boost::optional<std::string>& getName() const
{
return m_name;
}
void clearName()
{
m_name = boost::optional<std::string>();
}
private:
boost::optional<std::string> m_name;
};
I wouldn't call that a paradigm. This seems to be a solution for architecture, where a field may be in unspecified state (why not? Sometimes it is a sane requirement). Though, I don't like much this solution, because getter is supposed to return value (symmetrically, setter is supposed to set it) and the convention usually requires specific prototypes:
Type GetValue();
SetValue (const Type & newValue);
or
SetValue (Type & newValue);
or
SetValue (Type newValue);
You shall choose one of three setters depending on situation, usually the first or second one fits.
If a field may be in an unspecified state, I would choose another approach, as M M. suggests in his answer, I'll take liberty to provide an example:
class C
{
private:
int field;
bool fieldSet;
public:
C()
{
field = 0;
fieldSet = false;
}
bool IsFieldSet()
{
return fieldSet;
}
int GetField()
{
if (!fieldSet)
throw std::exception("Attempt to use unset field!");
return field;
}
void SetField(const int newValue)
{
field = newValue;
fieldSet = true;
}
};
Note though, that I wouldn't call this way of implementing getters evil. It may be just uncomfortable to use.

How to return a class object by reference in C++?

I have a class called Object which stores some data.
I would like to return it by reference using a function like this:
Object& return_Object();
Then, in my code, I would call it like this:
Object myObject = return_Object();
I have written code like this and it compiles. However, when I run the code, I consistently get a seg fault. What is the proper way to return a class object by reference?
You're probably returning an object that's on the stack. That is, return_Object() probably looks like this:
Object& return_Object()
{
Object object_to_return;
// ... do stuff ...
return object_to_return;
}
If this is what you're doing, you're out of luck - object_to_return has gone out of scope and been destructed at the end of return_Object, so myObject refers to a non-existent object. You either need to return by value, or return an Object declared in a wider scope or newed onto the heap.
You can only use
Object& return_Object();
if the object returned has a greater scope than the function. For example, you can use it if you have a class where it is encapsulated. If you create an object in your function, use pointers. If you want to modify an existing object, pass it as an argument.
class MyClass{
private:
Object myObj;
public:
Object& return_Object() {
return myObj;
}
Object* return_created_Object() {
return new Object();
}
bool modify_Object( Object& obj) {
// obj = myObj; return true; both possible
return obj.modifySomething() == true;
}
};
You can only return non-local objects by reference. The destructor may have invalidated some internal pointer, or whatever.
Don't be afraid of returning values -- it's fast!
I will show you some examples:
First example, do not return local scope object, for example:
const string &dontDoThis(const string &s)
{
string local = s;
return local;
}
You can't return local by reference, because local is destroyed at the end of the body of dontDoThis.
Second example, you can return by reference:
const string &shorterString(const string &s1, const string &s2)
{
return (s1.size() < s2.size()) ? s1 : s2;
}
Here, you can return by reference both s1 and s2 because they were defined before shorterString was called.
Third example:
char &get_val(string &str, string::size_type ix)
{
return str[ix];
}
usage code as below:
string s("123456");
cout << s << endl;
char &ch = get_val(s, 0);
ch = 'A';
cout << s << endl; // A23456
get_val can return elements of s by reference because s still exists after the call.
Fourth example
class Student
{
public:
string m_name;
int age;
string &getName();
};
string &Student::getName()
{
// you can return by reference
return m_name;
}
string& Test(Student &student)
{
// we can return `m_name` by reference here because `student` still exists after the call
return stu.m_name;
}
usage example:
Student student;
student.m_name = 'jack';
string name = student.getName();
// or
string name2 = Test(student);
Fifth example:
class String
{
private:
char *str_;
public:
String &operator=(const String &str);
};
String &String::operator=(const String &str)
{
if (this == &str)
{
return *this;
}
delete [] str_;
int length = strlen(str.str_);
str_ = new char[length + 1];
strcpy(str_, str.str_);
return *this;
}
You could then use the operator= above like this:
String a;
String b;
String c = b = a;
Well, it is maybe not a really beautiful solution in the code, but it is really beautiful in the interface of your function. And it is also very efficient. It is ideal if the second is more important for you (for example, you are developing a library).
The trick is this:
A line A a = b.make(); is internally converted to a constructor of A, i.e. as if you had written A a(b.make());.
Now b.make() should result a new class, with a callback function.
This whole thing can be fine handled only by classes, without any template.
Here is my minimal example. Check only the main(), as you can see it is simple. The internals aren't.
From the viewpoint of the speed: the size of a Factory::Mediator class is only 2 pointers, which is more that 1 but not more. And this is the only object in the whole thing which is transferred by value.
#include <stdio.h>
class Factory {
public:
class Mediator;
class Result {
public:
Result() {
printf ("Factory::Result::Result()\n");
};
Result(Mediator fm) {
printf ("Factory::Result::Result(Mediator)\n");
fm.call(this);
};
};
typedef void (*MakeMethod)(Factory* factory, Result* result);
class Mediator {
private:
Factory* factory;
MakeMethod makeMethod;
public:
Mediator(Factory* factory, MakeMethod makeMethod) {
printf ("Factory::Mediator::Mediator(Factory*, MakeMethod)\n");
this->factory = factory;
this->makeMethod = makeMethod;
};
void call(Result* result) {
printf ("Factory::Mediator::call(Result*)\n");
(*makeMethod)(factory, result);
};
};
};
class A;
class B : private Factory {
private:
int v;
public:
B(int v) {
printf ("B::B()\n");
this->v = v;
};
int getV() const {
printf ("B::getV()\n");
return v;
};
static void makeCb(Factory* f, Factory::Result* a);
Factory::Mediator make() {
printf ("Factory::Mediator B::make()\n");
return Factory::Mediator(static_cast<Factory*>(this), &B::makeCb);
};
};
class A : private Factory::Result {
friend class B;
private:
int v;
public:
A() {
printf ("A::A()\n");
v = 0;
};
A(Factory::Mediator fm) : Factory::Result(fm) {
printf ("A::A(Factory::Mediator)\n");
};
int getV() const {
printf ("A::getV()\n");
return v;
};
void setV(int v) {
printf ("A::setV(%i)\n", v);
this->v = v;
};
};
void B::makeCb(Factory* f, Factory::Result* r) {
printf ("B::makeCb(Factory*, Factory::Result*)\n");
B* b = static_cast<B*>(f);
A* a = static_cast<A*>(r);
a->setV(b->getV()+1);
};
int main(int argc, char **argv) {
B b(42);
A a = b.make();
printf ("a.v = %i\n", a.getV());
return 0;
}
It isn't really good practice to return an initiated object as it does go out of scope. There are rare instances that this is the desired option. It actually can be done if the class is a referencing counting smart pointer or some other smart pointer.
How does a reference-counting smart pointer's reference counting work?

passing an array of character to function c++

Let's say I have the following:
char cipan[9];
then what should I pass to the function? how about the get and set method??
I'm currently doing like this
set method
void setCipan(char cipan[]){
this->cipan = cipan;
}
and the get method
char getCipan(){
return cipan;
}
and I get an error when compiling??
Im totally blur.. can someone explain what should i pass to the function??
class userData{
private:
string name;
char dateCreate[9];
void userDataInput(string name,char dateCreate[]){
this->name = name;
this->dateCreate = dateCreate;
}
public:
//constructor
userData(string name){
userDataInput(name,dateCreate);
}
userData(string name,char dateCreate[]){
userDataInput(name,dateCreate);
}
//mutator methods
void changeName(string name){this->name = name;}
void changeDateCreate(char *dateCreate){this->dateCreate = dateCreate;}
//accesor methods
string getName(){return name;}
char *getDateCreate(){return dateCreate;}
};
I'd do the following:
void setCipan(const char* new_cipan)
{
strcpy(cipan, new_cipan);
}
const char* getCipan() const
{
return cipan;
}
Of course, the better approach is to use std::string:
void setCipan(const string& new_cipan)
{
cipan = new_cipan;
}
string getCipan() const
{
return cipan;
}
Constructor's purpose is to initialize class variables. I think it's unnecessary to call another method in the constructor to do initialization.
void userDataInput(string name,char dateCreate[]){
this->name = name;
this->dateCreate = dateCreate; // Both the dateCreate are class variables.
}
userData(string name){
userDataInput(name,dateCreate); // dateCreate is already a class variable.
}
dateCreate is the class scope variable. You are just passing it to a method, and re-assigning the same to dateCreate. Assignment operation doesn't copy elements of one array to another and are invalid operations.
To copy array elements, use std::copy instead.