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;
Related
I am using C++ 14 with clang on MacOS Sierra. I want to enforce a rule by design. Following is the rule.
I have a member variable in my class say:
unsigned int m_important_num;
There are 4 methods in my class.
fun1();
fun2();
fun3();
fun4();
Objective:
I want only fun2() to be able to change the value of m_important_num.
Question:
Is it possible to make it compiler error if any method other than fun2() changes the variable?
One possible way is to declare it const somehow empower fun2() to change const variables? Is this a good solution? Or are their any better solutions?
Secondary question:
Is it a wrong design to try do such a thing?
Sort of, with additional layer:
class S1 {
public:
void fun2() { /*Modify m_important_num */ }
unsigned int getImportantNum() const { return m_important_num;}
private:
unsigned int m_important_num;
};
class S2 : private S1
{
public:
void fun1();
using S1::fun2; // or void fun2() {S1::fun2();}
void fun3();
void fun4();
};
As Yakk commented, if func2 need access to S2 members, CRTP can solve that:
template <typename Derived>
class S1 {
public:
void fun2() { asDerived().foo3(); /*Modify m_important_num */ }
unsigned int getImportantNum() const { return m_important_num;}
private:
Derived& asDerived() { return stataic_cast<Derived&>(*this); }
private:
unsigned int m_important_num;
};
class S2 : private S1<S2>
{
// friend class S1<S2>; // If required.
public:
void fun1();
using S1::fun2; // or void fun2() {S1::fun2();}
void fun3();
void fun4();
};
Encapsulate it down. Put m_important_num in its own class. Aggregate it in your existing class. Have a getter for it. Then put fun2() as a member function of your inner class.
I little variant (if I understand correctly) of the Jeffrey solution: put the variable in an inner class and make it private; create a public getter and make func2() friend to the inner class.
I mean
struct foo
{
int f1 () { return b0.getVal(); }; // you can read `val` everywhere
void f2 () { b0.val = 42; }; // you can write `val` in f2()
void f3 () { /* b0.val = 42; ERROR ! */ }; // but only in f2()
class bar
{
private:
int val = 24;
public:
int getVal () { return val; }
friend void foo::f2 ();
};
bar b0;
};
In other words: friend is your friend.
If you want to prevent a method from modifying any member in the class you can use the trailing const identifier:
class something{
private:
unsigned int var;
public:
void fun1() const;
void fun2();
void fun3() const;
void fun4() const;
}
Here, only fun2() will be able to modify the variable.
I know there are lots of good answers, but there is also an option that you sort of alluded to in your question:
One possible way is to declare it const somehow empower fun2() to change const variables?
#include <iostream>
using uint = unsigned int;
class Test
{
const uint num;
public:
Test(uint _num)
:
num(_num)
{}
uint get_num() const
{
return num;
}
void can_change_num(uint _new_num)
{
uint& n(const_cast<uint&>(num));
n = _new_num;
}
void cant_change_num(uint _new_num)
{
// num = _new_num; // Doesn't compile
}
};
int main()
{
Test t(1);
std::cout << "Num is " << t.get_num() << "\n";
t.can_change_num(10);
std::cout << "Num is " << t.get_num() << "\n";
return 0;
}
Produces
Num is 1
Num is 10
You already got lots of good answers to your primary question. I'll try to address the secondary one.
Is it a wrong design to try do such a thing?
It's hard to say w/o knowing more about your design. In general anything like this detected during a code review would raise a big red flag. Such a protection makes sense in a case of a big class with convoluted logic/implementation. Otherwise why would you like to go an extra mile and make your code much more complicated? The fact you seek for this can indicate your class became unmanageable.
I'd recommend to consider splitting it to smaller parts with better defined logic where you won't worry such mistakes can happen easily.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to change a subclass values Capacity, RentRate and RentMin using operation overloading. I'm newish to c++, come from java.
I want to create the objects
VanIn Van7("Large", 200, 2.0);
ManVanIn ManVan8("Abc", 99999, "Medium", 100, 1.0);
ManVan8 = Van7;
Making ManVan8 values change from "Medium, 100, 1.0" to "Large, 200, 2.0" but I keep getting a object qualifer error at the operations overload method
using namespace std;
class AbstractVan {
private:
int RentMin;
string Drivername;
long DLno;
string Capacity;
float RentRate;
public:
AbstractVan(string Drivername, long DLno, string Capacity, int RentMin, float RentRate) : Capacity(Capacity), RentMin(RentMin), RentRate(RentRate), DLno(DLno), Drivername(Drivername) {}
void setCapacity(string cap) { Capacity = cap; }
void setRentRate(float rate) {RentRate = rate;}
void setRentMin(int min) {RentMin = min;}
string getCapacity() { return Capacity; }
float getRentRate() { return RentRate; }
int getRentMin() { return RentMin; }
virtual void print() = 0;
};
Derived class from AbstractVan
class VanIn : public AbstractVan {
public:
VanIn(string Capacity, int RentMin, float RentRate) : AbstractVan(Capacity, RentMin, RentRate) {}
AbstractVan(string Drivername, long DLno, string Capacity, int RentMin, float RentRate) : Capacity(Capacity), RentMin(RentMin), RentRate(RentRate), DLno(DLno), Drivername(Drivername) {}
Derived class from VanIn
class ManVanIn : public VanIn {
private:
string Drivername;
int DLno;
public:
ManVanIn(string Drivername, long DLno, string Capacity, int RentMin, float RentRate) : VanIn(Drivername, DLno, Capacity, RentMin, RentRate){}
void print() { cout << "Drivername " << this->Drivername << " Registration " << this->DLno << " - " << getCapacity() << endl; }
~ManVanIn() {cout << "Destroy ManVanIn" << endl;}
void operator = (const VanIn &D) {
setCapacity(D.getCapacity());
setRentRate(D.getRentRate());
setRentMin(D.getRentMin());
}
};
Entry
int main()
{
VanIn Van7("Large", 200, 2.0);
ManVanIn ManVan8("Abc", 99999, "Medium", 100,1.0);
ManVan8 = Van7;
ManVan8.print();
system("pause");
return 0;
};
First of all things, as you will see later on, it's good practice to define getters with const qualifier. Otherwise it cannot be called on const object - I will get into that later.
string getCapacity() const { return Capacity; }
float getRentRate() const { return RentRate; }
int getRentMin() const { return RentMin; }
By using const qualifier you declare, that these methods only read from object and they don't change anything within the object. By following this 'rule' print() should be declared with const qualifier as well:
virtual void print() const = 0;
Second thing is if you have at least one virtual method, destructor should be virtual as well.
virtual ~AbstractVan() = default;
Next problem is in your VanIn class. Definition of constructor is wrong. VanIn is derived class from AbstractVan, therefore before creating VanIn, base class (in this case AbstractVan) must be created. Since AbstractVan doesn't have default constructor you must call parametric one (which accepts 5 arguments) in initialization section. Like this:
VanIn(string Capacity, int RentMin, float RentRate)
: AbstractVan(/* 5 parameters MUST be here */) { }
Don't forget what order of parameters is in AbstractVan constructor(e.g. it won't accept float if it expects string).
Note: you might want to use const string& in this constructor instead of string. const string& means that it is read-only reference (no unnecessary copying).
Next issue is in ManVanIn class. I don't see use of private variables. Same thing will be saved in AbstractVan after its constructor is called. Also when you call constructor of ManVanIn you try to call VanIn constructor with invalid number of arguments. Your declared version expects 3, and you give 5.
Next one is not a issue but is a good practice. When you override virtual functions use override specifier, like this:
void print() const override { /* ... */ }
It is good practice because if you try to override function which is not virtual your program won't compile (you avoid a lot of mistakes by using this). For example if you declared print function in Abstract as I did and you try override function like this:
double print() override { /* ... */ }
or even like this
void print() override { /* ... */ }
compiler will warn you that you are overriding function which is not virtual. In first case it should be clear, you didn't declare print() member function returning double. In second case it is because of missing const qualifier.
The reason why getters should be const lies here:
void operator = (const VanIn &D) {
setCapacity(D.getCapacity());
setRentRate(D.getRentRate());
setRentMin(D.getRentMin());
}
Your operator = overload accepts one parameter which is const reference to VanIn object. What you say here is that you won't change VanIn object within the body of this function. Therefore compiler cannot call non-const methods on const objects. If you miss const qualifier in these cases your program won't even compile (it should give error about discarding cv-qualifier).
I have an object, every member variable in this object has a name which I can acquire it by calling get_name() ,what I want to do is concatenate all the names of the member variables in alphabetical order, then do something. for example:
class CXMLWrapper<class T>
{
public:
CXMLWrapper(const char* p_name) : m_local_name(p_name)
{
}
//skip the get_name(), set_name() and others
private:
string m_local_name;
T m_type_var;
}
class object
{
public:
object() : m_team("team"), m_base("base")
{
}
public:
CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;
...
}
I have to hard-code like this:
object o;
string sign = o.m_base.get_name();
sign += o.m_team.get_name();
I need a function to do this instead of copying and pasting when the object varies. Anyone has an idea?
One way to do this in normal C++, provided all of the members belong to the same class or are derived from some base class will be to use variable number of arguments to a function. An example follows.
#include <stdarg.h>
string concatenateNames(int numMembers, ...)
{
string output;
va_list args;
va_start(args, numMembers);
for(int i = 0; i < numMembers; i++)
{
MemberClass *pMember = va_arg(args, MemberClass*);
output += pMember->get_name();
}
va_end(args);
return output;
}
class Object
{
public:
MemberClass x;
MemberClass y;
MemberClass z;
};
int main()
{
Object o;
string sign = concatenateNames(3, &o.x, &o.y, &o.z);
}
If the types of all the members are different, you can look into variadic templates of C++11x: http://en.wikipedia.org/wiki/Variadic_Templates, but I can't seem to find a way to do otherwise.
If variables which have name have a same type (or these types belongs one hierarchy) you can use map of these vars. Is not good way, but maybe it helps you
Example
class object
{
public:
object() //: m_team("team"), m_base("base")
{
this->vars["m_team"] = CXMLWrapper<string>("team");
//.....
}
public:
map<string, CXMLWrapper<string> > vars;
/*CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;*/
...
}
object o;
string sign;
for(auto& x : o.vars)//i cannot remember syntax of for of map
sign += x.get_name;
PS Sorry for my writing mistakes. English in not my native language.
One method is to have an external library of member names which the CXMLWrapper class updates:-
class BaseXMLWrapper
{
public:
void ListMembers (const char *parent)
{
// find "parent" in m_types
// if found, output members of vector
// else output "type not found"
}
protected:
void RegisterInstance (const char *parent, const char *member)
{
// find 'parent' in m_types
// if not found, create a new vector and add it to m_types
// find 'member' in parent vector
// if not found, add it
}
private:
static std::map <const std::string, std::vector <const std::string> >
m_types;
};
class CXMLWrapper <class T, const char *parent> : BaseXMLWrapper
{
public:
CXMLWrapper(const char* p_name) : m_local_name(p_name)
{
RegisterInstance (parent, p_name);
}
// you could override assignments, copy and move constructors to not call RegisterInstance
//skip the get_name() set_name()
private:
m_local_name;
}
class object
{
public:
object() : m_team("team"), m_base("base")
{
}
public:
CXMLWrapper<string, "object"> m_team;
CXMLWrapper<string, "object"> m_base;
...
};
This does add overhead to the construction of objects, but as it's only a constructor overhead it might not affect overall system performance much.
This looks like a "observe pattern", you just need to keep a single copy in object as a member variable "string name_;", and pass the name_s's reference into CXMLWrapper like this:
class CXMLWrapper<class T>
{
public:
CXMLWrapper(const string &name)
: local_name_(name)
{
}
//skip the get_name() set_name()
private:
const string &local_name_;
}
class object
{
public:
object()
: team_("team"),
base_("base"),
m_team(team_)
, m_base(base_)
{
}
public:
string team_;
string base_;
CXMLWrapper<string> m_team;
CXMLWrapper<string> m_base;
}
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 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.