I know it may seem like this has been asked before but I've looked around and the static method didn't work for me. Here's my code:
struct Customer {
public:
string get_name();
private:
string customer,first, last;
};
Here's where I call the function:
void creation::new_account() {
Customer::get_name(); //line it gives the error on.
}
Here's an example of some code that compiles fine.
struct Creation { public: string get_date(); private: string date; };
then I call it the same way
void Creation::new_account() { Creation::get_date();}
Hence my confusion why one works and the other doesn't.
EDIT: Ok I get it, I just realized I was calling a function of another struct inside a function definition that's part of a different class. I got it, thanks to all who answered
It is not declared static (needs to be static std::string get_name();). However, get_name() for Customer is a specific attribute of a Customer instance so having it static does not make sense, that is the same name for all instances of Customer. Declare an object of Customer and use it. It would make sense to have the name provided to the constructor of Customer, as surely a customer cannot exist without a name:
class Customer {
public:
Customer(std::string a_first_name,
std::string a_last_name) : first_name_(std::move(a_first_name)),
last_name_(std::move(a_last_name)) {}
std::string get_name();
private:
std::string first_name_;
std::string last_name_;
};
Declare an instance of Customer:
Customer c("stack", "overflow");
std::cout << c.get_name() << "\n";
Since your get_name is not declared static, it is a member function.
You probably need some constructors in your Customer class. Assuming you have some, you could code
Customer cust1("foo123","John","Doe");
string name1 = cust1.get_name();
You need an object (here cust1) to call its get_name member function (or method).
Time to spend many hours reading a good C++ programming book.
"The static method didn't work for me". It's not a method it's how the language works.
If you want to call some method without a concrete object, you need it to be static. Otherwise, you need an object.
Your code will work with one of the following :
struct Customer {
public:
static string get_name();
private:
string customer,first, last;
};
or
void creation::new_account() {
Customer c;
//stuff
c.get_name();
}
Related
Hello guys a have a problem, that i can't access field tablica[i]->help, in generuj function, its saying that this field is not existing in class Task.
How can i achieve it ?
class Task
{
protected:
string contents;
int id_pyt;
int nr_pyt;
};
class Task4Answ : public Task
{
private:
int help;
public:
Task4Answ(string contents1, int id,int nr,int help1)
{
contents=contents1;
id_pyt=id;
nr_pyt=nr;
help=help1;
}
};
class TaskCollection
{
protected:
Task *collection[60];
public:
friend class Generator;
TaskCollection()
{
collection[0] = new Task4Answ("Ile jest por roku w Polsce? \na) 1 \nb) 2 \nc) 3 \nd) 4",1,0);
collection[1] = new Task4Answ("Kto wygral tegoroczny Roland Garros? \na) Federer \nb) Djokovic \nc) Nadal \nd) Thiem",1,1);
class Generator
{
protected:
Task *tablica[10];
TaskCollection T1;
public:
Generator(){}
void Generuj()
{
if(T1.collection[x]->id_pyt==1)
{
tablica[i]=new Task4Answ("0",0,0);
tablica[i]->contents=T1.collection[x]->contents;
tablica[i]->id_pyt=T1.collection[x]->id_pyt;
tablica[i]->nr_pyt=T1.collection[x]->nr_pyt;
tablica[i]->help=T1.collection[x]->help; //here is the problem
}
}
}
Or maybe there is some other solution of the project im doing now.
Thanks for any help.
The problem is in this line:
tablica[i]=new Task4Answ("0",0,0);
Although you have called the Task4Answ constructor, you are also assigning the memory address returned by new to a Task pointer. Effectively, you have casted the Task4Answ pointer to a Task pointer. On the lines that follow, C++ only sees tablica[i] as a reference to a Task pointer. You need to change:
protected:
Task *tablica[10];
TaskCollection T1;
...to this:
protected:
Task4Answ *tablica[10]; // Task was changed to Task4Answ
TaskCollection T1;
That should allow C++ to see tablica as an array of Task4Answ pointers instead of Task pointers.
Edit: it looks like help is also private. You will have to change help to public or add TaskCollection::TaskCollection() as a friend. Otherwise, C++ will not let you get or set help.
Edit: the OP added that tablica[i] might contain instances of other classes that inherit from Task. In that case, you could do something like this:
void Generuj()
{
if(T1.collection[x]->id_pyt==1)
{
Task4Answ* newTask = new Task4Answ("0",0,0);
newTask->contents=T1.collection[x]->contents;
newTask->id_pyt=T1.collection[x]->id_pyt;
newTask->nr_pyt=T1.collection[x]->nr_pyt;
newTask->help=T1.collection[x]->help; // You will still have to change this from being private.
tablica[i] = newTask;
}
}
}
Later on, in order to access help, you will need to implement some sort of way of checking whether tablica[i] is a Task4Answ and not an instance of some other class that inherits from Task, perhaps by implementing a method in Task named IsTask4Answ that returns false in Task but is overridden to return True in Task4Answ. You can then cast the pointer back to Task4Answ with something like the static_cast operator. In other words:
// Add these functions to the class definitions:
virtual bool Task::IsTask4Answ() const {
return false;
}
bool Task4Answ::IsTask4Answ() const override {
return true;
}
// Later, you can do this:
if(tablica[i].IsTask4Answ()){
Task4Answ* t = static_cast<Task4Answ*>(tablica[i]);
t->help; // Again, you'll have to change this from being private.
}
Although I suggest figuring out a different data structure where you do not need to do any casting, this will allow you to access help.
Do note the virtual keyword in the first function above; it allows the function to be dynamically bound, which means that the code will check whether to call Task::IsTask4Answ() or Task4Answ::IsTask4Answ() at runtime instead of at compile time.
I am making an ecosystem in C++ where every ANIMAL on my playing_field will grow_older() at the end of the year.
class ANIMAL
{
private:
int age;
public:
ANIMAL()
{
age=0;
}
static void grow_older(){ age++; }
};
I know that static methods can only use static data, but is there any elegant way to have something similar to an ANIMAL.grow_older();? I could iterate through my playing_field and call grow_older(); on each animal, but I was hoping there is some concept out there that I'm not aware of that avoids iterating through every instance of ANIMAL explicitly.
There's no elegant way to increate the value of data members from many objects at once, so your options seem to be to either have a single static age (which I assume is not valid for your use case), to increase the age of all objects one at a time (by iterating through whatever container they're in to find each), or adopting a different solution completely.
One possible alternative solution is to not store age as a data member at all, but rather store a time_of_birth as a data member, and also keep track of a current_time as a static data member. Your class would then look something like:
class ANIMAL
{
private:
int time_of_birth;
static int current_time;
public:
ANIMAL()
{
time_of_birth=current_time;
}
static void grow_older(){ current_time++; }
int age() { return current_time - time_of_birth; }
};
int ANIMAL::current_time = 0; /* defined in a source, not header file */
If each time you must increase the age you also need to examine the age (for example, to see if the animal must now be dead), there probably is no savings since you need to iterate through your menagerie anyway. On the other hand, if you do not need to examine the age as (or more) often than you need to increase it, this approach should perform better due to resulting in less work.
Since my last question had too much code in it, I tried to make the simplest example of what I'm trying to do. Take this for example,..
#include <iostream>
using namespace std;
class String
{
public:
private:
};
class ClassTwo
{
public:
int memberVariable;
private:
};
class ClassOne
{
public:
ClassOne (ClassTwo&, String&);
~ClassOne();
private:
ClassTwo& classTwoReference;
String& stringReference;
};
ClassOne::ClassOne (ClassTwo& two, String& string)
: classTwoReference (two), stringReference (string)
{
two.memberVariable = 3;
}
ClassOne::~ClassOne()
{
}
int main()
{
String stringObject;
ClassTwo classTwoObject;
ClassOne classOneObject (classTwoObject, stringObject);
}
In JUCE, which is the API I'm using to code a VST Plugin, there is a string class that JUCE names "String". I'm not sure exactly what the constructor does, but you can use something like this to create a String object.
String newString("string");
The ClassTwo in my case, is the AudioProcessor class which has a public member variable that I can access from ClassOne like this.
two.memberVariable = 3;
The ClassOne in my case, is a custom Component(I named it PixelSlider) that I'm using in my GUI. It uses a slider listener to check the status of a slider and modify the member variable in ClassTwo(AudioProcessor). I can do this fine using the method above, but the issue is that I want to create as many ClassOne(PixelSlider) objects as I need. I want to pass them a String object that tells them what member variable of ClassTwo(AudioProcessor) to modify. Logically, this would be done by passing a reference to a String object with the same string value as the name of the ClassTwo member variable. Like this,...
ClassOne::ClassOne (ClassTwo& two, String& string)
: classTwoReference (two), stringReference (string)
{
two.(string) = 3;
}
This doesn't work in JUCE, but can anybody tell me a way to get this done without having to create a bunch of different classes almost exactly like ClassOne(PixelSlider) that modify different ClassTwo(AudioProcessor) member variables?
If I understand correctly, you're trying to bind a PixelSlider target to a member of AudioProcessor at runtime, which, as you've discovered, can't be done the way you suggest ( two.(string) = 3 ). One way of achieving this binding would be to use the command pattern (http://sourcemaking.com/design_patterns/command/cpp/2).
AudioProcessor could expose a collection of these command objects for each modifiable property ...
AudioProcessorCommand
AudioProcessor::GetCommandByName(String const& properyName) const
{
...
}
... which you can pass to the constructor of PixelSlider. Something along the lines of ...
PixelSlider::PixelSlider(AudioProcessorCommand& command)
: command_{command}
{
...
}
When the PixelSlider's value changes you would invoke the command ...
command_(this->value_);
I have a class with private and public members I am trying to use a getter Get_Words() to access the private word member. This all compiles but when the value from dir[NORTH].Get_Words() = "NORTH"; Whenever the word was just a public function without the Get_Words() member function using dir[NORTh].word = "NORTH";
Why isn't the Get_Words assigning the value correctly to word?
class Words
{
public:
static void Set_Words();
string Get_Words();
private:
string word;
}
string Word::Get_Words()
{
return word;
}
...
dir[NORTH].Get_Word() = "NORTH";
and I also tried
dir[NORTH].Get_Word() = Set_Word( string "North");
I'm pretty sure I did the setter wrong but I am new to object oriented programming in c++ and can't figure out the best way to do this.
std::string Get_Word() returns by value, aka it makes a copy of the word and returns it. When you try to assign to it, you are trying to assign to a right hand reference, which is impossible.
A way around this would to return a reference to word:
std::string& Get_Word();
But that is generally considered bad practice as the reference can outlive the class. A better way is to provide a setter along side the getter:
void Set_Word(const std::string& w) {word=w;}
or even better:
template <typename T>
void Set_Word(T&& w) {word=std::foreward<T>(w);}
To get a private value, usually a public get function is implemented.
You want to set the value - usually a public set function is implemented for this task:
void Set_Word(string& newValue) { ... }
Or implement the Getter as returning a reference, as Vlad from Moscow stated.
I've started learnig C++ (year ago) mostly because it's univerzal language IMO, and beacause almost everything is possible.
but one thing isn't so:
for example we are writing some code inside an object(class) and we need to find out it's name somehow:
class Test
{
public: const char* getMyIdentiferName()
{
// what now??
}
};
well the best option is to use 'this' keywod but that wouldn't help cos 'this' cant return name?
Test thatsMyName;
const char* = thtsMyName.getMyIdentiferName(); //return string "thatsMyName" how?
how do we get 'thatsMyName' string in in some generic function or even template??
ANOTHER EXAMPLE:(please answer this too)
how do we get typeid of some class?
class MyType
{
public: type_info getType()
{
return typeid(this); //that wont work of course :)
{
};
this looks funny but if any of you have some idea on how to achive similar task...
thanks alot.
EDIT: OK, everybodey say it's impossible to get the name of an object, I found out how to get the name:
class Test
{
public: string getObjectName()
{
string arg = typeid(*this).name();
arg.erase(arg.begin(), arg.begin() + 5);
arg.erase(0,1);
return arg;
}
};
int main()
{
Test thisIsMyName;
cout << thisIsMyName.getObjectName() << endl;
cin.ignore();
return 0;
}
EDIT:
Big thanks to Fiktik answering my second example who found the way oon how to get the type_info of the object!
The first thing you are asking is not possible. At least not directly.
You could create a macro for variable declaration that would register its name somewhere, something like this:
#define CREATE_VARIABLE(type, name) registerVariable<type>(#name); type name
but this is quite cumbersome and cannot be used everywhere. Why would you even want to have this functionality?
The second thing should work with only little adjustments:
class MyType
{
public:
const type_info& getType()
{
return typeid(*this);
}
};
What would you need the variable name for? What you're trying to do is impossible; inside an classes' methods, the name of the variable used for accessing an object isn't known.
Consider this example:
Test * myTest = new Test();
Test * myTest2 = myTest;
const char* identifier = myTest2->getMyIdentifierName();
What should getMyIdentifierName() return? "myTest"? "myTest2"? Nothing at all, since the object was allocated dynamically, and therefore no variable can really claim to "hold" the object?
If you just want to know the variable name which you are currently using for referring to an object, why not just use a string literal for it and pass it wherever you need it? But that doesn't seem to make sense in any real-world application.
If you need a name (i.e., a unique identifier) for an object at runtime, you'll best give the class a member name and initialize that with whatever you need.
Getting the "identifier name" of an object won't work, since there is no unique identifier for an object (other than it's address, to be gotten with &). An unlimited number of references/pointers can designate the same object; at the same time, the language allows objects to be reached by other means than identifiers (v[0] where v is a vector is an object, but not an identifier). This is the case in all programming languages that I know, and I know a dozen of them.
As for your second question, you can return a reference to an std::type_info.
struct Test
{
// pretty useless method
std::type_info const &type() const { return typeid(*this); }
};
int main()
{
Test a;
std::cout << a.type().name() << "\n";
}