suppose i have a simple C++ class :
class Calc
{
private:
int a;
public:
Calc(){
a = 0;
}
void seta(int a){
this->a = a;
}
int geta(){
return a;
}
};
Now, suppose, in main i create a object of this class, and take two inputs from user : var_name which is name of instance variable in string format, and action which is set or get in string format. For ex : if var_name = "a" and action == "get" , then i should be able to call geta() fn. Is there any way to achieve this in C++.
pls dont provide if..then..else kind of soln. I want to write a generic code which need not be updated as more members are added in class Calc.
You cannot dynamically modify C++ types. However, it sounds like you just want a way to set and read attributes. You don't need to modify your class structure for this, there are other alternative solutions. For example you could use an std::map:
class Calc
{
private:
std::map<std::string, int> attributes;
public:
Calc(){}
void setAttr(const std::string& name, int value){
attributes[name] = value;
}
int getAttr(const std::string& name){
return attributes[name];
}
};
Related
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
}
Please read the question before marking it as a duplicate.
So here is what I am trying to achieve. Basically I have a string which contains some value initially.
I have split my program into many classes for modularity.(you can suggest a better way to do that - currently each file contains one class in it) So say for eg I want to operate on the data with class1 , then the modified string needs to get operated by class2 and so on.
eg.
Initial entry is "hello world"
first class -> "hello WORLD"
second class -> "H#l#o WORLD"
thiid class -> "##l#o WORLD"
and so on...
Reading everywhere that global variables are a big no no when coming to issues and downsides it has. So keeping that in mind what would be the best way I can share seamlessly between classes.
I also thought of passing the string as a pointer to each function but I thought there might be better alternatives to it. Please suggest.
Thanks for stopping by to read my que and help me out.
Without knowing exactly why you want to do this it is hard to answer. But I don't see what is wrong with just passing the string as a reference to each class much like you suggest:
class StringModifier1 {
public:
void operator()(std::string& s) {
// modify s...
}
};
class StringModifier2 {
public:
void operator()(std::string& s) {
// modify s...
}
};
class StringModifier3 {
public:
void operator()(std::string& s) {
// modify s
}
};
int main() {
std::string myString = "hello world";
StringModifier1 modifier1;
StringModifier2 modifier2;
StringModifier3 modifier3;
modifier1(myString);
modifier2(myString);
modifier3(myString);
}
Live demo.
In some cases you might want the classes to store a pointer or reference to the string:
class StringModifier1 {
private:
std::string& s;
void func1() {
// modify s...
}
void func2() {
// modify s some more...
}
public:
StringModifier1(std::string& s) : s(s) {}
void execute() {
func1();
func2();
}
};
int main() {
std::string myString = "hello world";
StringModifier1 modifier1(myString);
modifier1.execute();
StringModifier2 modifier2(myString);
modifier2.execute();
StringModifier3 modifier3(myString);
modifier3.execute();
}
Live demo.
You might want one class to own and provide access to the string and the other classes have a pointer or reference to the owning class.
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.
Hi I'm a beginner C++ developer..I have a problem with a code that I post so it's easier to understand the problem.
Obj.h
class Obj : public QObject
{
Q_OBJECT
public:
typedef void (*factionState)();
struct Tran {
factionState Action;
unsigned int nextState;
};
void processAction(myState)
{
Tran const*t = myarrayAction + myState
*(t->action)();
myState=t->nextState;
}
private:
Tran const *myarrayAction;
unsigned int numStates;
protected:
myObj;
myState;
public:
Obj (Tran *arrayAction, const int nStates, const int i) {arrayAction=myarrayAction, numStates = nStates;};
void doNothing(){printf ("Do NOthing called\n")};
Obj_1.h
#include "Obj.h"
const int Obj_1=1
class Obj_1 : public Obj
{
private:
typedef enum {
OffState,
InitState,
RunState,
}state ;
static Obj::Tran myarrayAction[3];
public:
Obj_1() : Obj(myarrayAction, 3, Obj_1) {myState=OffState, myObj=Obj_1,init();};
private:
void init();
void GoToInitState();
void GoToRunState();
};
Obj_1.cpp
void Obj_1::init()
{
myarrayAction[3] = {
{&Obj::doNothing, OffState},
{&Obj_1::GoToInitState, InitState},
{&Obj_1::GoToRunState, RunState},
};
}
void Obj_1::GoToInitState()
{
// code;
}
void Obj_1::GoToRunState()
{
// code;
}
When I build the code I have this error:
no match for 'operator=' (operand types are 'Obj::Tran' and ''). So I tried to remove '=' and write Obj1::init like this
myarrayAction[3] {
{&Obj::doNothing, OffState},
{&Obj_1::GoToInitState, InitState},
{&Obj_1::GoToRunState, RunState},
};
But I have a sintax error..Any ideas??
Thanks
A couple of things. First, when Obj_1::init() executes, myarrayAction has already been initialized by the constructor. The { } syntax, which works for some array initializations, is not going to work here. You need an object (not a list of initializers) on the right-hand side of =.
Second, it looks like you want Obj_1::init() to set the contents of all three of the Obj::Tran objects within myarrayAction. But when you start a statement like this, myarrayAction[3] =, it is going to try to set the array member myarrayAction[3], that is, the fourth member of the array myarrayAction (whose first three members are myarrayAction[0], myarrayAction[1], myarrayAction[2]). But this array has only three members.
You are better off to write something like this:
myarrayAction[0] = ... ;
myarrayAction[1] = ... ;
myarrayAction[2] = ... ;
In the ... parts you call the constructors of the three objects you want to store at those three locations, passing the values you want to the parameters of each of these constructors.
Another thing you could do is, instead of using Obj::Tran* to represent an array of Obj::Tran, actually use a class to implement this array. If you know STL you could write std::vector<Obj::Tran>, for example. Or you could write your own class, depending on what you want. If you write a class, you can also write a constructor that takes the list of values you want as parameters, though you will not be able to organize them into sublists with nested { } as you could with an array initializer list.
How to Define or Implement C# Property in ISO C++ ?
Assume following C# code :
int _id;
int ID
{
get { return _id; }
set { _id = value; }
}
I know C# convert the get and set lines to getXXX and setXXX methods in compile time. in C++ , programmers usually define these two function manually like :
int _id;
int getID() { return _id; }
void setID(int newID) { _id = newID; }
but, I want to have the C# syntax or a stuff like it in order to have a simple usability.
In C#, we can use properties like :
ID = 10; // calling set function
int CurrentID = ID; // calling get function
In C++, we can use our function like :
setID(10); // calling set function
int CurrentID = getID(); // calling get function
Now tell me how can I implement the C# properties in ISO C++.
thanks.
As Alexandre C. has already stated, it's very awkward and not really worth it, but to give an example of how you might do it.
template <typename TClass, typename TProperty>
class Property
{
private:
void (TClass::*m_fp_set)(TProperty value);
TProperty (TClass::*m_fp_get)();
TClass * m_class;
inline TProperty Get(void)
{
return (m_class->*m_fp_get)();
}
inline void Set(TProperty value)
{
(m_class->*m_fp_set)(value);
}
public:
Property()
{
m_class = NULL;
m_fp_set = NULL;
m_fp_set = NULL;
}
void Init(TClass* p_class, TProperty (TClass::*p_fp_get)(void), void (TClass::*p_fp_set)(TProperty))
{
m_class = p_class;
m_fp_set = p_fp_set;
m_fp_get = p_fp_get;
}
inline operator TProperty(void)
{
return this->Get();
}
inline TProperty operator=(TProperty value)
{
this->Set(value);
}
};
In your class where you wish to use it, you create a new field for the property, and you must call Init to pass your get/set methods to the property. (pref in .ctor).
class MyClass {
private:
int _id;
int getID() { return _id; }
void setID(int newID) { _id = newID; }
public:
Property<MyClass, int> Id;
MyClass() {
Id.Init(this, &MyClass::getID, &MyClass::setID);
}
};
Short answer: you can't.
Long answer: You could try to simulate them via proxy classes, but believe me this is not worth the minor incovenience in having set/get functions.
You'd have basically to define a class which forwards all the behavior of the variable. This is insanely hard to get right, and impossible to be made generic.
Quite simply. I'd argue this even has no overhead compared to making the variable public. However, you can't modify this any further. Unless, of course, you add two more template parameters that are call backs to functions to call when getting and setting.
template<typename TNDataType>
class CProperty
{
public:
typedef TNDataType TDDataType;
private:
TDDataType m_Value;
public:
inline TDDataType& operator=(const TDDataType& Value)
{
m_Value = Value;
return *this;
}
inline operator TDDataType&()
{
return m_Value;
}
};
EDIT: Don't make the call back functions template parameters, just data members that are constant and must be initialized in the constructor for the property. This inherently has greater overhead than simply writing a get and set method your self, because you're making function calls inside of your gets and sets this way. The callbacks will be set at run-time, not compile-time.