I am trying to understand delegation in c++. I read that "delegation is pointer to function", and i saw several examples, but unfortunately I cant get it. I have created code to try, because I thought that maybe while programming i will understand it. Unfortunately I didn't.
#include <iostream>
using namespace std;
class person{
private:
int age;
public:
person(age){
this->age = age;
}
// virtual void changeAge(int arg) = 0;
};
class addNumber {
public:
int changeAge(int arg) {
arg += arg+1;
}
};
int main(){
person Olaf;
}
So based on this source I tried:
Olaf = &addNumber::changeAge(10);
or
addNumber test;
Olaf = &addNumber::changeAge(10);
Both does not work. That means program is not compiling.
I want to make person object to use changeName of addNumber class method to change the age of instance person class.
First, let's use a typedef for the function:
typedef int agechanger(int);
this makes a new type, agechanger, which will be used in code for passing the function instances around.
Now, you should give your person class a proper constructor, and properly incapsulate the age field providing a public getter. Then add a method that accepts a function as argument, function of type agechanger, of course.
class person
{
private:
int age;
public:
person(int age){
this->age = age;
}
int getAge() const {
return age;
}
void changeAge(agechanger f)
{
age = f(age);
}
};
Then define a function that fits our type, inside a class:
class addNumber {
public:
static int changeAge(int arg) {
return arg + 1;
}
};
Notice that the function is marked as static and returns the passed int incremented by one.
Let's test everything in a main:
int main()
{
person Olaf(100); //instance of person, the old Olaf
Olaf.changeAge(addNumber::changeAge); //pass the function to the person method
std::cout << Olaf.getAge() << std::endl; //Olaf should be even older, now
}
Let's make and use a different function, ouside a class, this time:
int younger(int age)
{
return age -10;
}
int main(){
person Olaf(100);
Olaf.changeAge(younger);
std::cout << Olaf.getAge() << std::endl; // Olaf is much younger now!
}
I hope that having code that works is going to help you understand things better. The topic you're asking about, here, is generally considered advanced, while I think you should review some more basic topics of c++, first (functions and classes, for example).
In C++11 and later you have closures (e.g. thru std::function etc...) and lambda expressions (that is, anonymous functions)
But you don't exactly have delegation in C++, even if you also have pointers to functions and pointers to member functions. But closures and lambda expressions are nearly equivalent, in power of expression, to delegation.
You should read SICP then some good C++ programming book to understand these notions.
Related
I have a class that has a few static functions that can be called even if there is no instance of that class. There is also a method init() that I use to set some variables. This method is not static thus it needs an instance. Now if this was done I want the static methods to behave differently. Sort of like:
static foo(){
if(noInstance()){
doA();
}else(){
doB();
}
}
Is this even possible? Or a bad idea and should just make the user call different methods if there is an instance?
Thanks
EDIT
It sounds weird but this is my use case:
class A{
public:
static inline bool hasInstance = false;
int data;
static int getData(){
if(hasInstance){
return data; // Can't do this from a static function
}else{
return 0;
}
}
};
I know that I cant access the data from a static function beacuse there is no this pointer. I'm coding a library and I want the user to be able to use the static method if he dosen't want an instance but if there is an instance it should make use of the data of its instance.
If had an idea but I don't know wether that's good style:
static int getData(A *ref){
if(ref != nullptr){
return data;
}else{
return 0;
}
}
I'd glad to hear from someone with more experience wether I should do that.
I think you can use a static variable, let it be named count. You initialize count with 0, and every time you create an instance of that class, you increment count. If count is 0, that means you did not created any instance, therefore you can't use some methods.
I'm coding a library and I want the user to be able to use the static method if he dosen't want an instance but if there is an instance it should make use of the data of its instance.
In general, free functions are recommended rather than member functions (gotw). It is actually rare to have good reasons to make a static function a member function. It would need to be a member if it would need access to privates of the class, but that doesnt seem to be the case here and then it still could be a friend function.
Let's look at your approach:
static int getData(A *ref){
if(ref != nullptr){
return data;
}else{
return 0;
}
}
You probably meant to write ref->data;, also I guess you are not merely returning the value of the member. That would be of little use, because If I have an instance I can get my hands on x.data without needing to call getData. And I suppose 0 is just a placeholder for someother value that you have there in the real code.
I am going a bit subjective now...
If I was a user of your library, I would want to know if getData returns data from one of the objects I did create or something else. Having one and the same function that does both would confuse me. I don't like pointers and I am scared of nullpointers, so if you force me to write
getData(nullptr);
this would not make me happy. I would like to have two different functions:
int getData() { return 0; }
int getData(const A& x) { return x.data; }
If I have no instance, I can call the first, if I have one I can call the second.
Not sure what is your final goal, but I would recommend reconsidering your design, because this static/hasInstance behavior smells.
Anyway, here is what you need:
using namespace std;
#include <iostream>
class MyClass
{
private:
static bool hasInstance;
public:
MyClass()
{
hasInstance = true;
}
static void foo()
{
if (hasInstance) {
std::cout << "I have an instance\n";
}
else {
std::cout << "No instance\n";
}
}
};
bool MyClass::hasInstance = false;
int main () {
MyClass::foo();
MyClass a;
a.foo();
MyClass::foo();
return 0;
}
EDIT:
Don't use it in real code. If you just curious, you can do almost everything in C++, so you could pass the object sometimes, it's dirty and ugly, but just for the demo:
using namespace std;
#include <iostream>
class MyClass
{
private:
int someVariable;
public:
MyClass()
{
someVariable = 42;
}
static void foo(MyClass *obj = nullptr)
{
if (obj) {
std::cout << obj->someVariable << std::endl;
}
else {
std::cout << "No instance\n";
}
}
};
int main () {
MyClass::foo();
MyClass a;
a.foo(&a);
MyClass::foo(&a);
return 0;
}
I am new to C++ programming and I need to create an object and name it with a string written on keyboard. However I tried to use pointers and variables, but when I declare an object (let’s say an int) there is no way to give its name after something written by user. I’ll do my best to picture that, forgive me for being so simple.
int main() {
string x;
std::cin>>x;
int x;
}
I would like to create an int object whose name is the string x previously declared and filled by user on keyboard. However this gives me an error, clearly, and pointers do not seem to work. Is there any other way? Thank you all in advance.
class A{
public:
A(){}
A(std::string _name): name{_name}{}
void setName(std::string _name)
{
name = _name;
}
std::string name;
}
this is how you object can look like.
you can creat it like this
int main()
{
string x;
std::cin>>x;
A a(x); //one option;
A b;
b.setName(x);//second option
}
I'm currently working on my first project using classes and objects, and I've run into a bit of a roadblock with my setter. I made up an example to illustrate the issue I'm running into (all one file for the sake of simplicity).
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class Example1
{
public:
Example1() { name = "Mike"; }
Example1(string aName) { name = aName; }
string GetName() const { return name; }
void SetName(string newName) { name = newName; }
private:
string name;
};
class Example2
{
public:
Example2() : anObj() {}
Example2(string aName) : anObj(aName) {}
Example1 GetObj() const { return anObj; }
void SetObj(string objName) { anObj.SetName(objName); }
private:
Example1 anObj;
};
int main()
{
Example2 myObj;
cout << myObj.GetObj().GetName() << endl;
myObj.GetObj().SetName("Stan");
cout << myObj.GetObj().GetName() << endl;
}
Output:
Mike
Mike
The idea is to alter the member object in Example2 by using the member object's setter method, but the setter method doesn't seem to be working the way I expected.
I tried accessing the member by moving it to public (in Example2) and using dot notation, and that successfully changed the name. I'm not sure what the differentiation is, but, since the getter is working properly, I feel like something is wrong with how I'm using the setter.
The original problem I was trying to solve was having a Game class with a Player class member object. The idea is that the player could change their name if they wanted to.
Appreciate any help. Thanks.
All your getters return a new object. Don't. Let them return a const &. But then you need a non const getter when you modify objects to call the setters:
const Example1& GetObj() const;
Example1& GetObj();
And now, the objects that are stored underneath will be updated, and not just their copies. Same for the strings.
You can also see the fact that the setters are not working on the proper objects by using a debugger.
I am a C++ newbie and I need help with a strange issue (or at least its strange to me)
I have a class as such:
class Myclass {
private:
int A;
// some other stuff...
public:
// constructor and stuff...
void setA(int a);
int* getA_addr();
};
void Myclass::setA(int a){
A = a;
};
int* Myclass::getA_addr(){
return &A;
};
Now, I want to modify A in main() and I am not using any other methods in the class (I did it by using extra methods and now I want to see how I can do it without using those extras). I have a function as such:
void change(int *ptr, int tmp){
*ptr = tmp;
};
In a call to this function, I do the passing as such: change(obj.getA_addr(), other arguments...) where obj is an instance of Myclass.
When done in this way, I receive no compilation errors but I also can't seem to modify A (of obj). As a debug effort, I tried to print the address of A (of obj) by directly calling getA_addr(). I saw that with every call, the function returns a different address. So I am assuming that I am not passing the intended address into the function.
I have no idea why this is happening and would like to know. Also, the way I'm trying to do this is most likely not at all accurate so please, if you can provide a solution, it would be appreciated. Thanks.
EDIT: Here's the most minimal code I could come up with that reproduces the error
#include <iostream>
#define MAX_SIZE 10
using namespace std;
class Student {
private:
int mt1;
public:
Student();
void setMt1(int in_mt1);
int* getMt1();
};
Student::Student() {};
void Student::setMt1(int in_mt1) { mt1 = in_mt1; };
int* Student::getMt1(){ return &mt1; };
class Course {
private:
Student entries[MAX_SIZE];
int num;
public:
Course();
void addStudent(Student in_student);
Student getStudent(int index);
};
Course::Course(){ num = 0; };
void Course::addStudent(Student in_student){
entries[num] = in_student;
num++;
};
Student Course::getStudent(int index){ return entries[index]; };
int main() {
void updateStudentScore(int *uscore, int newscore);
Course mycourse;
Student tmp_student;
tmp_student.setMt1(60);
mycourse.addStudent(tmp_student);
cout<<mycourse.getStudent(0).getMt1()<<"\t"<<*mycourse.getStudent(0).getMt1()<<endl;
updateStudentScore(mycourse.getStudent(0).getMt1(), 90);
cout<<mycourse.getStudent(0).getMt1()<<"\t"<<*mycourse.getStudent(0).getMt1()<<endl;
return 0;
}
void updateStudentScore(int *uscore, int newscore){
*uscore = newscore;
};
I am fairly certain that my understanding of pointers and passing-by-whatevers is lacking and the way I defined functions here is creating the bug. I am sorry to inconvenience you guys. I would appreciate it if you could take a look.
Looking at your student/course code, i notice that Course::getStudent returns a Student rather than a Student &. Basically, that means each time you call getStudent(x), you get a temporary copy of student x, whose getMt1 function will give you a pointer to a temporary field, and any changes you make won't even survive past that statement.
If you have getStudent return a reference or pointer instead, your changes should persist to the Student contained in the array. (They still won't affect tmp_student, though, because addStudent copied it to add it to the array. If you want that reliably, then you need to redo quite a bit of stuff.)
I'm new to the site (and to programming) so I hope I post this question appropriately and under all the proper guidelines of the site. Ok, here it goes:
So I pretty new to C++ and am trying to create classes for a program. I have to construct "container and entity classes", but where I'm struggling is trying to nail down the proper syntax for my getter and setter functions in the container class. So here's the code I have so far:
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
using namespace std;
const int MAX_STUDENTS=100;
const int MAX_COURSES=25;
const int NAME_SIZE=30;
const int COURSE_COLUMNS=4;
const int GRADE_ROWS=10;
//Entity Classes
class Course
{
//Two private member variables
private:
string courseText;
int courseID;
public:
//Constructor
Course(void)
{
//Just providing initial value to the two object variables
courseText;
courseID=-1;
}
//Setters and Getters for each variable
string getCourseText(){
return courseText;}
void setCourseText(string userEnteredText){
courseText = userEnteredText;}
int getCourseID(){
return courseID;}
void setCourseID(int userEnteredID){
courseID = userEnteredID;}
};
class Student
{
//Private member variables
private:
string studentText;
int studentID;
int** coursesAndGrades;
int enrolledCoursesCount;
int timesReallocatedColumns;
int timesReallocatedRows;
public:
//Constructor
Student(void)
{
//Just providing initial value to the object variables
studentText;
studentID=-1;
coursesAndGrades = new int*[GRADE_ROWS+1];
for(int i=0;i<(GRADE_ROWS+1);i++)
{
coursesAndGrades[i] = new int[COURSE_COLUMNS];
}
enrolledCoursesCount=0;
timesReallocatedColumns=0;
timesReallocatedRows=0;
}
//Setters and Getters for each variable
string getStudentText(){
return studentText;}
void setStudentText(string userEnteredText){
studentText = userEnteredText;}
int getStudentID(){
return studentID;}
void setCourseID(int userEnteredID){
studentID = userEnteredID;}
int getCoursesAndGrades(int gradeRow, int courseColumn){
return coursesAndGrades[gradeRow][courseColumn];}
void setCoursesAndGrades(int gradeRow, int courseColumn, int entry){
coursesAndGrades[gradeRow][courseColumn]=entry;}
int getEnrolledCoursesCount(){
return enrolledCoursesCount;}
void setEnrolledCoursesCount(int enrolledCount){
enrolledCoursesCount = enrolledCount;}
int getTimesReallocatedColumns(){
return timesReallocatedColumns;}
void setTimesReallocatedColumns(int reallocColumnCount){
timesReallocatedColumns = reallocColumnCount;}
int getTimesReallocatedRows(){
return timesReallocatedRows;}
void setTimesReallocatedRows(int reallocRowCount){
timesReallocatedRows = reallocRowCount;}
};
Now, I've got a container class called GradeBook which contains dynamically allocated arrays of these two entity class objects.
class GradeBook
{
private:
Course* courses;
Student* students;
public:
//Constructor
GradeBook(void)
{
courses = new Course [MAX_COURSES];
students = new Student [MAX_STUDENTS];
}
}
I'm trying to figure out the proper way to translate the setter and getter functions from my entity classes to the container class so I can change individual elements of each class object in the dynamically allocated array. These changes will happen in more public member functions in the container class, but I'm completely stumped. I hope this question makes sense, and I'm not looking for anyone to write all of the setters and getters for me, I just need someone to point me in the proper direction for the syntax. Thanks everyone who made it through this!
If you will have something like this:
class GradeBook
{
public:
...
Student& student(int idx) { /*some boundary check here*/
return students[idx]; }
}
then you can use that method as:
GradeBook theBook;
...
auto idOfFirstStudent = theBook.student(0).getStudentID();
You just need to decide what that student() method shall return: it can return reference (as above) or pointer to student (instance). In later case you can return nullptr in case of out-of-bound errors. In first case the only reasonable option is to throw an error.
So there's no magic needed here, but you do need to decide how you want to do it. One way would be to just write something like:
void GradeBook::setCourseText(int i, const string &txt) {
courses[i].setCourseText(txt);
}
BTW, I would highly recommend using std::vector and at() rather than new.