Getter function returns the wrong value? - c++

In my utils class I have a private solution dir string - it is set in the constructor (hardcoded). I have a getter function that returns the string. In another file I have a utils instance (pointer). When I call the getter function it returns empty.
main.cpp
utils* myUtils = new utils();
std::cout << myUtils->getSolutionDir() + " is the current directory" << std::endl;
delete myUtils;
utils.hpp
public:
utils ();
~utils ();
std::string getSolutionDir();
private:
std::string _solutionDir;
utils.cpp
utils::utils () {
std::string _solutionDir = "C:\\Users\\user\\Documents\\Coding\\CodeBlocks\\MettaRPG";
}
utils::~utils () {}
std::string utils::getSolutionDir() {
return _solutionDir;
}
OUTPUT (GCC compiler):
is the current directory

Take a look at this line in the constructor:
std::string _solutionDir = "C:\\Users\\user\\Documents\\Coding\\CodeBlocks\\MettaRPG";
This line declares a local variable named _solutionDir and sets that equal to the indicated string, rather than taking the existing data member named _solutionDir and changing its value. To address this, remove the std::string from this line.
Alternatively, if you have a C++11 compiler, consider just changing your class to look like this:
public:
~utils ();
std::string getSolutionDir();
private:
std::string _solutionDir = "C:\\Users\\user\\Documents\\Coding\\CodeBlocks\\MettaRPG";

Related

Initialize const variable in constructor after changing it

I have a Client class, which receives an std::string variable called emailAdress. This is what the code looks like now, and it works:
private:
const std::string email;
Client::Client(std::string emailAddress) : email{emailAddress}
{
}
Now, I want to check if the email contains characters like an # or a valid name with no strange characters. I want to do this with regex.
Now, my question is, how do I initialize the const std::string email variable after changing the parameter variable? It says it doesn't want to because it is a const variable, that is why it is in the initialization list of the constructor right now.
You can pass the parameter to a function, and let the function return the modified string.
class Client {
private:
const std::string email;
static std::string validateEmail(std::string email) {
// ...
return modifiedEmail;
}
public:
Client::Client(std::string emailAddress) : email{validateEmail(std::move(emailAddress))}
{
}
};

Is there any way we can use a const variable defined in one function can be used by other function in the same program in c++

How can we use const std::string variable defined in one function to be used in another function of the same program.
int sample::convert()
{
fun()
{
//returns string;
}
const std::string sender = fun()
}
void sample::write()
{
//I want to use sender variable here like below
std::string var;
var = sender;
}
No that's not possible.
Why don't you have sender as a member variable and make sample a class if it is currently a namespace?
If the actual problem is that you don't know how to define constant member variables, it's just like you define it in the function itself:
class sample
{
const std::string sender = "sample";
// Other members...
};
There are two known methods.
First, return the string to use it somewhere (it's probably not what you wanted, but it'll work).
std::string sample::convert()
{
const std::string sender = "sample"
return sender;
}
void sample::write()
{
//I want to use sender variable here like below
std::string var;
var = sender();
}
Or, better declare this variable as a class member variable:
class sample {
std::string sender = "sample"; // if not it's going to be modified, then use 'const'
public:
...
}
I got the answer finally.
We need to declare a char * globally. Then using const_cast <char *> we can convert the constant string to char and assign it.
Example:
in .h file:
char * abc;
in .cc file:
func()
{
const std::string cde = "Hello";
//now to use this constant string in another function,we use const cast and
//assign it to abc like below
abc = const_cast <char *>(cde.c_str());
}

Losing value of member variable after returning from constructor C++

Here is the code sample I am working on.
Header file has below code:
class TestClass
{
private:
LPCWSTR m_variable;
public:
TestClass(const std::string& variable);
}
Here is the implementation:
TestClass::TestClass(const std::string& variable)
{
std::wstring stemp = std::wstring(variable.begin(), variable.end());
m_variable= stemp.c_str();
}
Here is the code how I make the call
std::string tempStr = "Panda";
TestClass *test = new TestClass(tempStr);
I stepped through debugger and see that while in constructor the value looks good L"Panda". But as soon as I step out of debugger I no longer see the data for my variable.
stemp.c_str() returns a non-owning pointer to the contents of the string. And std::wstring stemp, which owns the data backing the result of .c_str(), ceases to exist the moment you return from the constructor.
Change your class to store a const std::wstring directly, so you have an owned, persistent copy of the string. You can then safely call .c_str() on the member whenever you need a LPCWSTR:
class TestClass
{
private:
const std::wstring m_variable;
public:
TestClass(const std::string& variable);
}
TestClass::TestClass(const std::string& variable) : m_variable(variable.begin(), variable.end()) {}

Using maps inside class and accessing values via get() and set() functions from other class

I am unable to use add values this map defined in header file as protected attribute from class member function.
class xyz{
protected:
map < string, string > *tagsMap;
public:
xyz();
//set Tags
void addTag(string _tagName, string _tagValue) const;
}
// In cpp class,
//set new Tags
void xyz::addTag(string _tagName, string _tagValue) const {
//map < string, string > tagsMap ;
//gives error until I uncomment above line, but thats local map
tagsMap.insert(pair<string, string>(_tagName, _tagValue));
// first insert function version (single parameter):
tagsMap .insert(pair<string, string>(_tagName, _tagValue));
for (auto& t : tagsMap )
cout << "addTag():" << t.first << "=" << t.second << endl;
}
You have 3 problems:
1) Class member is declared a pointer
The commented line inside addTag():
// map < string, string > tagsMap;
It is not a pointer, which is the reason why it works if you uncomment the local map declaration.
However, this is not correct logically since it's not a member of your class - it shadows your tagsMap class member.
Thus, you need to declare tagsMap in your xyz class a non-pointer.
map < string, string > *tagsMap;
// ^ remove asterisk '*'
2) Missing Semicolon after class definition
Add ; semicolon, after your class definition
class xyz {
...
}
// ^^^ add semicolon here
3) Const function
Remove const in addTag() to be able to write on tagsMap class member
void xyz::addTag(string _tagName, string _tagValue) const { .. }
// ^^^^^ remove const
void addTag(string _tagName, string _tagValue) const;
// ^^^^^ remove const
Yes pointer was not needed.
It worked after making the function non-const as suggested by #codekaizer in comments above.
class xyz{
protected:
map < string, string > tagsMap;
public:
xyz();
//set Tags
void addTag(string _tagName, string _tagValue);
}
// In cpp class,
void xyz::addTag(string _tagName, string _tagValue) {
tagsMap.insert(pair<string, string>(_tagName, _tagValue));
}

Use singleton classes in c++

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;