I have a class with 2 variables. They are public.
I want to initialise them in such a way that one is always a multiple of the other, and when i update the first, the other will automatically update.
In my class declaration:
`
public:
Int variable1;
Int variable2 = (10*variable1);
`
When I update variable1, i want to check what the updated value of variable2 is, and do some stuff based upon that result.
variable1++;
If (variable2 > 10)
{
//Do stuff
}
So I know that I could get around this by updating the second variable, but I know there must be a way to have he second variable constantly update. The problem is clearly in the declaration, but "const", or "static", won't help... I don't think. If I could find an eloquent way to phrase the problem, I'm sure i could google the answer. But I can't!
You just cannot do it like that. Correct way is through encapsulation.
In the example below, just call the getters to get the value (inlined = as fast as a direct access) and you can modify only variable1. You could add a set_variable2 method but it would have little sense.
public:
inline int get_variable1() const { return variable1; }
inline int get_variable2() const { return variable1*10; }
inline void set_variable1(int new_value) { variable1=new_value; }
private:
int variable1;
Simply don't do it... create only one variable and multiply it when needed.
The best way would be to just use a multiple of variable 1 whenever you would use variable 2
for your if statement, use
if((variable1 * 10) > 10){
//do stuff
}
Related
I am attempting to use std::unordered_set as a hash table to store many CreditCard's. CreditCard and another class CardDatabase are defined as follows:
class CreditCard {
private:
string cardHolder;
unsigned long long cardNumber;
int limit;
int balance;
public:
CreditCard(string in_cardHolder, string in_cardNumber, int in_limit) {
cardHolder = in_cardHolder;
cardNumber = stoll(in_cardNumber);
limit = in_limit;
balance = 0;
}
void ChangeBalance(int amount) const {
balance += amount; // SECOND ERROR
}
};
class CardDatabase {
private:
unordered_set<CreditCard> cards;
unordered_set<CreditCard>::iterator iter;
public:
CardDatabase() { }
void AddCard(cardHolder, cardNumber, int limit) {
CreditCard tempCard = CreditCard(cardHolder, cardNumber, limit);
cards.insert(tempCard);
}
void Charge(string cardHolder, int chargeAmount) {
iter = cards.find(cardHolder);
iter->ChangeBalance(chargeAmount); // FIRST ERROR
}
}
Initially I was getting the following compile error at FIRST ERROR: Member function 'ChangeBalance' not viable: 'this' argument has type 'const CreditCard', but function is not marked const. So, I added the "const" to the ChangeBalance function. However, after doing that I get the following compile error at SECOND ERROR: Cannot assign to non-static member within const member function 'ChangeBalance'.
Is there any way to fix this error without changing balance to a static variable? It is obviously important that the balance be different for each CreditCard instance.
Any help is appreciated.
EDIT:
Thank you all for your quick answers. I feel I should clarify something. I already added the proper hash functionality elsewhere in my code:
namespace std {
template <>
struct hash<CreditCard> {
size_t operator()(const CreditCard& cc) const
{
return hash<string>()(cc.GetCardHolder());
}
}
}
Also, the code I posted initially pasted is from a much larger code base and I didn't delete all the necessary namespacing stuff at first before posting the question. My apologies for the confusion.
Members of an unordered_set are constant, and cannot be changed once they're in the unordered_set, by default. You are trying to change the objects in the set, and the compiler is properly telling you that you can't do this.
The only possible way to do this correctly (explained only for educational purposes, because this is bad class design):
Explicitly declare the individual fields that can be modified in this manner as mutable.
Use a custom hash function with your unordered_set, and the hash function must exclude the value of mutable fields from the value of the calculated hash.
Otherwise, modifying the contents of the object in the set obviously changes its hash value, which will result in undefined behavior.
Again, this is explained for informational purposes only. This is not a good class design.
The clean way to do this would be to assign a unique identifier to each CreditCard (you know, like a credit card number?), and use an ordinary std::map, to look up CreditCards by their number.
It's not appropriate for ChangeBalance to have const semantics. By the very nature of it's name, you're modifying the object. Make the function non-const.
void ChangeBalance(int amount) {
balance += amount;
}
The other problem is that you didn't call your function correctly. You should instead do this:
iter->ChangeBalance(chargeAmount);
I will mention there are cases where you want to modify values in a const object, and there is a mutable type modifier for that. Do not use it to solve your current error, however!
void ChangeBalance(int amount) should not be const - it is changing the object.
The problem is before in the iterator: cards.find returns a const object, so you are not allowed to change it.
A way to resolve that is to make your cards set a set of pointers to cards, not of cards; or to use another way to find the matching card
Playing fast and loose with the C++ syntax in that thar code, Hoss. Plenty of errors wait around the corner
First Error:
iter->CreditCard::ChangeBalance(chargeAmount);
should be
iter->ChangeBalance(chargeAmount);
Straight-up bad syntax that likely results from flailing around because of the errors resulting from unordered_set having no idea how to hash a CreditCard. Give this a read: How do I use unordered_set? That said, unordered_set is probably not the right solution for this job. std::map<std::string, CreditCard> looks more on point.
Using the wrong solution to fix the above problem lead to the
Second Error:
void ChangeBalance(int amount) const
const on a method means the method cannot change the state of the object. in ChangeBalance balance += amount; attempts to change the state of the object by updating a member variable.
In addition, the compiler is going to HATE the CreditCard:: in this:
CreditCard::CreditCard(string in_cardHolder, string in_cardNumber, int in_limit) {
cardHolder = in_cardHolder;
cardNumber = stoll(in_cardNumber);
limit = in_limit;
balance = 0;
}
Another solution is to make the "balance" as a static member.
class CreditCard {
private:
string cardHolder;
unsigned long long cardNumber;
int limit;
static int balance;
....
}
And then initialize it in cpp file
int CreditCard::balance = 0;
This code may not be very secure. But this can be one of the workaround.
I have an integer constant that is to be defined at runtime. This constant needs to be available globally and across multiple source files. I currently have the following simplified situation:
ClassA.h declares extern const int someConstant;
ClassA.cpp uses someConstant at some point.
Constants.h declares extern const int someConstant;
main.cpp includes ClassA.h and Constants.h, declares const int someConstant, and at some point during main() tries to initialize someConstant to the real value during runtime.
This works flawlessly with a char * constant that I use to have the name of the program globally available across all files, and it's declared and defined exactly like the one I'm trying to declare and define here but I can't get it to work with an int.
I get first an error: uninitialized const ‘someConstant’ [-fpermissive] at the line I'm declaring it in main.cpp, and later on I get an error: assignment of read-only variable ‘someConstant’ which I presume is because someConstant is getting default initialized to begin with.
Is there a way to do what I'm trying to achieve here? Thanks in advance!
EDIT (per request from #WhozCraig): Believe me: it is constant. The reason I'm not posting MCVE is because of three reasons: this is an assignment, the source is in Spanish, and because I really wanted to keep the question as general (and reusable) as possible. I started out writing the example and midway it striked me as not the clearest question. I'll try to explain again.
I'm asked to build a program that creates a process that in turn spawns two children (those in turn will spawn two more each, and so on). The program takes as single argument the number of generations it will have to spawn. Essentially creating sort of a binary tree of processes. Each process has to provide information about himself, his parent, the relationship with the original process, and his children (if any).
So, in the example above, ClassA is really a class containing information about the process (PID, PPID, children's PIDs, degree of relation with the original process, etc). For each fork I create a new instance of this class, so I can "save" this information and print it on screen.
When I'm defining the relationship with the original process, there's a single point in which I need to know the argument used when calling the program to check if this process has no children (to change the output of that particular process). That's the constant I need from main: the number of generations to be spawned, the "deepness" of the tree.
EDIT 2: I'll have to apologize, it's been a long day and I wasn't thinking straight. I switched the sources from C to C++ just to use some OO features and completely forgot to think inside of the OO paradigm. I just realized while I was explaining this that I might solve this with a static/class variable inside my class (initialized with the original process), it might not be constant (although semantically it is) but it should work, right? Moreover I also realized I could just initialize the children of the last generation with some impossible PID value and use that to check if it is the last generation.
Sorry guys and thank you for your help: it seems the question was valid but it was the wrong question to ask all along. New mantra: walk off the computer and relax.
But just to recap and to stay on point, it is absolutely impossible to create a global constant that would be defined at runtime in C++, like #Jerry101 says?
In C/C++, a const is defined at compile time. It cannot be set at runtime.
The reason you can set a const char *xyz; at runtime is this declares a non-const pointer to a const char. Tricky language.
So if you want an int that can be determined in main() and not changed afterwards, you can write a getter int xyz() that returns a static value that gets initialized in main() or in the getter.
(BTW, it's not a good idea to declare the same extern variable in more than one header file.)
As others have mentioned, your variable is far from being constant if you set it only at run-time. You cannot "travel back in time" and include a value gained during the program's execution into the program itself before it is being built.
What you can still do, of course, is to define which components of your program have which kind of access (read or write) to your variable.
If I were you, I would turn the global variable into a static member variable of a class with a public getter function and private setter function. Declare the code which needs to set the value as a friend.
class SomeConstant
{
public:
static int get()
{
return someConstant;
}
private:
friend int main(); // this should probably not be `main` in real code
static void set(int value)
{
someConstant = value;
}
static int someConstant = 0;
};
In main:
int main()
{
SomeConstant::set(123);
}
Anywhere else:
void f()
{
int i = SomeConstant::get();
}
You can further hide the class with some syntactic sugar:
int someConstant()
{
return SomeConstant::get();
}
// ...
void f()
{
int i = someConstant();
}
Finally, add some error checking to make sure you notice if you try to access the value before it is set:
class SomeConstant
{
public:
static int get()
{
assert(valueSet);
return someConstant;
}
private:
friend int main(); // this should probably not be `main` in real code
static void set(int value)
{
someConstant = value;
valueSet = true;
}
static bool valueSet = false;
static int someConstant = 0;
};
As far as your edit is concerned:
Nothing of this has anything to do with "OO". Object-oriented programming is about virtual functions, and I don't see how your problem is related to virtual functions.
char * - means ur creating a pointer to char datatype.
int - on other hand creates a variable. u cant declare a const variable without value so i suggest u create a int * and use it in place of int. and if u are passing it into functions make it as const
eg: int *myconstant=&xyz;
....
my_function(myconstant);
}
//function decleration
void my_function(const int* myconst)
{
....
}
const qualifier means variable must initialized in declaration point. If you are trying to change her value at runtime, you get UB.
Well, the use of const in C++ is for the compiler to know the value of a variable at compile time, so that it can perform value substitution(much like #define but much more better) whenever it encounters the variable. So you must always assign a value to a const when u define it, except when you are making an explicit declaration using extern. You can use a local int to receive the real value at run time and then you can define and initialize a const int with that local int value.
int l_int;
cout<<"Enter an int";
cin>>l_int;
const int constNum = l_int;
I have a function in a class the more or less works like so:
class Player {
private:
Object* minions[16]
public:
void Summon(Object* obj);
};
Player::Summon(Object* obj) {
static int i = 0;
if (i == 16)
return;
minions[i] = obj;
i++;
}
The problem arise when trying to use more than one player, like so:
Player playerone;
Player playerthree;
playerone.Summon(new Object("o1"));
playerthree.Summon(new Object("o2"));
o1 is located in playerone.minions[0], as is expected, however, o2 is located in playerthree.minions[1], the Summon() function using the same i variable. Is there a way to make the Summon() function use a static i variable for a single instance, but use separate i variables for each instance? I know I could do something like make a for loop to the first spot in minions[] equal to NULL, or make i a member of Player directly, but I want to know if there is a better way before I do either of those.
Change Object* minions[16]; to a std::vector<Object*> minions;. That way you can just use minions.size() to know how many there are, or minions.push_back(obj); to add one without worrying about array index stuff.
Why don't you simply put i in each Player? I'd rename it something like summonned_minion_count, but that's the actual intent of what you want to do.
Making a local variable static is effectively making it global. You should simply make i a data member of class Player. And probably give it a more descriptive name.
You need to make your i a member variable of Player.
Or even better you could do something like this:
#include <vector>
class Player {
private:
static int const MAX_MINION_COUNT = 16;
std::vector<Object *> minions;
public:
void Summon(Object* obj) {
if (minions.size() < MAX_MINION_COUNT) {
minions.push_back(obj);
}
}
};
I have a class, say
class AddElement{
int a,b,c;
}
With methods to set/get a,b,c... My question is definitely a logic question - say I implement AddElement as follows:
int Value=1;
Value+=AddElement.get_a()+AddElement.get_b()+AddElement.get_b();
Now imagine I want to do the above except 'a,b,c' are now arrays, and instead of 'adding' I do scalar addition. At runtime sometimes I need 'a' but not 'b' or 'c', so I could rewrite as:
Value+=AddElement.get_a();
(Of course the += is overloaded to represent a scalar addition... and Value is the same size as a) - Other times I might only need b or c to be added etc...
Is there a way to go about selecting which elements, a,b,c, I want to initialize and later use at runtime? ( i.e. I don't want to malloc a huge array if I'm not going to use it).
In the end I need a class that has a,b,c and then methods that can operate on any combination of a,b, or c - having the user define what methods they need at runtime (via some kind of flag, or config file).
Currently I'm doing the following:
Value+=AddElement.get_a()*FlagA+AddElement.get_b()*FlagB+AddElement.get_c()*FlagC;
where FlagA=1 if you want to use 'a' in the addition or 0 if you don't want it to be included (The same for FlagB and FlagC). This is costly if the array 'a' is very large.
I'm probably just not thinking hard enough, but this problem has been bothering me. If you need me to better define the issue I will try, but I believe this is enough to get my point across.
Edit 2
I also forgot to add that I can't use any conditionals during the implementation of the addition (this is going to be used in a CUDA kernel and I can't have any thread diverngance - I was hoping to avoid mentioning CUDA since this is entirely a c++ question)
Edit 3
I believe what I need to do is use virtual functions. I want to call the function in the same manner, except have it execute a case specific function.
Edit 4
I would appreciate if someone took a look at my solution - maybe its too 'exotic' and there's a simpler method to accomplish the same end. Thanks for all the suggestions!
Edit 5
Thanks to another user I looked at the Strategic Design Pattern - and this is exactly the solution I used for this problem. I had never heard of that before and ended up rethinking a problem that has already been done (took a while for someone to mention something about it). So the solution:
Determine Algorithm at Runtime = Strategic Design Pattern.
You provide your class with a method GetSumOfActiveElements that does just what the name says. You can make this class virtual and create subclasses for each scenario, or have the class manage the memory efficiently in some other way.
What about something like this?
vector<pair<int, bool>> values(3);
values[0].first = 1;
values[0].second = false;
values[1].first = 2;
values[1].second = true;
values[2].first = 3;
values[2].second = false;
int sum = values[0].first * values[0].second +
values[1].first * values[1].second +
values[2].first * values[2].second;
You could probably make this cleaner/extensible using functors and <algorithm>.
It's not clear to me why conditionals are a bad thing - multiplication will be more expensive I would think. Is this a CUDA limitation or idiosyncracy?
If you allowed conditionals you could make your vector member a class that encapsulated a value and an in-use flag, and use filtering algorithms to perform aggregation as required.
Does this rough outline of code work for you?
struct S{
int getx() {return 0;}
int gety() {return 0;}
int getz() {return 0;}
};
int main(){
int (S::*p[3])(); // allocate as per need
p[0] = &S::getx; // populate as per need at run time
p[1] = &S::gety;
p[2] = 0;
int val = 1;
S obj;
int nCount = 0;
while(p[nCount] != 0)
val += (obj.*(p[nCount++]))();
}
EDIT 2: #Steve Townsend: That's right. I missed that conditional stuff.
How about this.
struct S{
int getx() {return 0;}
int gety() {return 0;}
int getz() {return 0;}
S(){}
S(S &obj, int (S::*p)()){
val += (obj.*p)();
}
static int val;
};
int S::val = 0;
int main(){
S obj;
S buf[] = {S(obj, &S::getx), S(obj, &S::gety)}; // the magic happens here in
// the constructor
}
So I think I got it -
struct S{
int x,y;
bool needx,needy;
};
class AnyFunction {
protected:
S Vals;
int TotalValue;
public:
virtual void SetValues(void) =0;
virtual void AddValues(void) =0;
}
class ImplementationFunc1 : public AnyFunction {
public:
void SetValues(S * Vals) { S.x=Vals->xval; }
void AddValues(void){ TotalValue+=Vals->x; }
}
class ImplementationFunc2 : public AnyFunction {
public:
void SetValues(S * Vals) {S.x=Vals->xval;S.y=Vals->yval;}
void AddValues(void){ TotalValue+=(Vals->x+Vals->y); }
}
int main(){
S SVals;
AnyFunction * APointerToAnyFunction;
// read a file that says if we need either x or y
SVals.needx=true; // (i.e. read from file)
SVals.needy=false; // (read from file)
if(Svals.needx){
SVals.x=Xfromfile;
if (Svals.needy){
ImplementationFunc2 Imp1;
SVals.y=yfromfile;
APointerToAnyFunction=&Imp1;
}
else{
ImplementationFunc1 Imp2;
APointerToAnyFunction=&Imp2;
}
}
...
// blah set some values
...
// So now I can call the function the same way (i.e. the call is always the same, no matter what kind of addition it needs to do), but I have all
// the logic for the conditions done _outside_ the addition
APointerToAnyFunction->AddValues();
So that should basically do it! no I can use the call: "APointerToAnyFunction->AddValues()" To perform the addition. The implementation can be determined by flags at the beginning of the program, then I can write a different class for each condition that i need to satisfy, and then have my polymorphic class inherit the properties of the base class.
Sorry if I did not fully define my problem, or the statement was vague - I didn't really know exactly how to do what I was explaining, but knew it was possible. Is this the right way to go about this? Is there a more efficient way?
Thanks to all who responded. Of course when x and y are arrays, I dynamically allocate x and y when necessary...
How about a std::vector of elements?
Problem spec is a bit unclear, to say the least, but I think that would work for you.
Cheers & hth.,
For debugging, I would like to add some counter variables to my class. But it would be nice to do it without changing the header to cause much recompiling.
If Ive understood the keyword correctly, the following two snippets would be quite identical. Assuming of course that there is only one instance.
class FooA
{
public:
FooA() : count(0) {}
~FooA() {}
void update()
{
++count;
}
private:
int count;
};
vs.
class FooB
{
public:
FooB() {}
~FooB() {}
void update()
{
static int count = 0;
++count;
}
};
In FooA, count can be accessed anywhere within the class, and also bloats the header, as the variable should be removed when not needed anymore.
In FooB, the variable is only visible within the one function where it exists. Easy to remove later. The only drawback I can think of is the fact that FooB's count is shared among all instances of the class, but thats not a problem in my case.
Is this correct use of the keyword? I assume that once count is created in FooB, it stays created and is not re-initialized to zero every call to update.
Are there any other caveats or headsup I should be aware of?
Edit: After being notified that this would cause problems in multithreaded environments, I clarify that my codebase is singlethreaded.
Your assumptions about static function variables are correct. If you access this from multiple threads, it may not be correct. Consider using InterlockedIncrement().
What you really want, for your long term C++ toolbox is a threadsafe, general purpose debug counters class that allows you to drop it in anywhere and use it, and be accessible from anywhere else to print it. If your code is performance sensitive, you probably want it to automatically do nothing in non-debug builds.
The interface for such a class would probably look like:
class Counters {
public:
// Counters singleton request pattern.
// Counters::get()["my-counter"]++;
static Counters& get() {
if (!_counters) _counters = new Counters();
}
// Bad idea if you want to deal with multithreaded things.
// If you do, either provide an Increment(int inc_by); function instead of this,
// or return some sort of atomic counter instead of an int.
int& operator[](const string& key) {
if (__DEBUG__) {
return _counter_map.operator[](key);
} else {
return _bogus;
}
}
// you have to deal with exposing iteration support.
private:
Counters() {}
// Kill copy and operator=
void Counters(const Counters&);
Counters& operator=(const Counters&);
// Singleton member.
static Counters* _counters;
// Map to store the counters.
std::map<string, int> _counter_map;
// Bogus counter for opt builds.
int _bogus;
};
Once you have this, you can drop it in at will wherever you want in your .cpp file by calling:
void Foo::update() {
// Leave this in permanently, it will automatically get killed in OPT.
Counters::get()["update-counter"]++;
}
And in your main, if you have built in iteration support, you do:
int main(...) {
...
for (Counters::const_iterator i = Counters::get().begin(); i != Countes::get().end(); ++i) {
cout << i.first << ": " << i.second;
}
...
}
Creating the counters class is somewhat heavy weight, but if you are doing a bunch of cpp coding, you may find it useful to write once and then be able to just link it in as part of any lib.
The major problems with static variables occur when they are used together with multi-threading. If your app is single-threaded, what you are doing is quite correct.
What I usually do in this situation is to put count in a anonymous namespace in the source file for the class. This means that you can add/remove the variable at will, it can can used anywhere in the file, and there is no chance of a name conflict. It does have the drawback that it can only be used in functions in the source file, not inlined functions in the header file, but I think that is what you want.
In file FooC.cpp
namespace {
int count=0;
}
void FooC::update()
{
++count;
}