swap(string1,string2) will swap two strings values easily while I use it in Main Function, But if I use it in another function and call it from main function it won't work!
this works:
int main()
{
string name1="A",name2="B";
swap(name1,name2);
}
but this one does not:
string name1="A",name2="B"; // Global Here
void exchange (string one,string two)
{
swap(one,two);
}
int main()
{
exchange(name1,name2);
}
where is the problem?
Pass the strings by reference instead of by value, otherwise exchange will modify local copies of one and two.
string name1="A", name2="B"; // Global Here
void exchange(string& one, string& two)
{
swap(one,two);
}
int main()
{
cout << name1 << "\n" << name2 << endl;
exchange(name1, name2);
cout << name1 << "\n" << name2 << endl;
}
Output:
A
B
B
A
Well, the values of the copies one and two actually are swapped. It won't affect the variables name1 and name2, of course. Assuming you want the values of these strings being swapped, you should pass the arguments by reference
void exchange(string& one, string& two) {
...
}
void exchange (string& one,string& two)
{
swap(one,two);
}
This should work. The amperstand (&) means that you are passing the arguments by reference, and that the function is allowed to modify the initial strings that were passed as parameters. If you do not use &, the strings will be passed by value and you will only modify copies of the actual strings.
Related
# include <iostream>
# include <string>
using std::string;
using std::cout;
using std::endl;
string func() {
string abc = "some string";
return abc;
}
void func1(string s) {
cout << "I got this: " << s << endl;
}
int main() {
func1(func());
}
This gives:
$ ./a.out
I got this: some string
How/why does this code work ? I wonder because abc went out of scope and got destroyed as soon as the call to func() completed. So a copy of abc cannot be/should not be available in variable s in function func1 Is this understanding correct ?
The return value is copied from the local variable, effectively creating a new string object.
However, RVO (returned value optimization) should eliminate this step.
Try single stepping your code in a debugger. You should see the std::string copy constructor called for the return line. Be sure to compile with debug enabled and optimizers off.
Your code is essentially asking:
"Call func1, and in order for func1 to work I have to receive a string which we can use by calling the copy constructor on that string. The parameter for func1 we want to come from the return value of func (which we know has to be a string since its explicitly defined".
abc goes out of scope only after the copy constructor is called on the return value of func() which passes the value of the string. In theory you could have written it passed by reference or constant reference:
void func1(string& s) {
cout << "I got this: " << s << endl;
}
Which allows func1 to directly access the string in memory through a pointer (and also change it, if your code was meant to.)
void func1(string const& s) {
cout << "I got this: " << s << endl;
}
Which provides a constant reference to the string from func(). This ensures that you get a pointer to the data and that you won't change its contents. Typically passing data by constant reference (const&) is desirable because it's very fast and keeps your code from accidentally changing data that it shouldn't.
You really only need to pass by value if you're going to manipulate the data once you pass it to the new function, saving you the resources of creating another new container to handle the manipulation:
void func1(string s) {
s += " some extra stuff to add to the end of the string"; //append some new data
cout << "I got this: " << s << endl;
}
Lets take the example some of the codes like the following use objects but can access their members directly without using any '.' operator
Eg-1
#include <iostream>
#include <string>
using namespace std;
int main () {
string mystr;
cout << "What's your name? ";
getline (cin, mystr);
cout << "Hello " << mystr << ".\n";
cout << "What is your favorite team? ";
getline (cin, mystr);
cout << "I like " << mystr << " too!\n";
return 0;
}
Here mystr is an object of std::string but it can access the group of characters inside it without using the '.' operator it should be
getline(cin,mystr.(member_name)); //Here member name is the name of the member which is there inside the class std::string and stores the data
But the actual working code is
getline(cin,mystr);
Second thing what is indirection
Edit 1:
Ok let me put this in a more simpler way if i have some class which has some data members and if i want to use any data member then i need to refer it from the object like
Eg-2
class reff{
public:
int a;
int b;
}
reff per;
per.a=36;
This statement tells that to access any class' members we need to refer it from the object but the same is not happening in the example of std:: string which i have mentioned above mystr is an object so it must be having some data member to store the data if i want to display the data inside a std::string object then i should mention the data member's name along with the objects name but in Eg-1 only object's name is mentioned.
The reason the call to getline(cin,mystr); does not directly specify any of the members of mystr is because the getline() function requires a string object, not one of its member variables. The actual implementation will access the individual members, but as a user of the string class, you don't need to (or want to) know those details. This concept is known as encapsulation, and allows you to seperate what a thing does (stores and allows access to a string of characters) from how it does it (pointers and length counters, static buffers, or whatever).
In your example:
class reff{
public:
int a;
int b;
};
reff per;
per.a=36;
you directly access the a member, but we could write a function which requires a reference to a reff object to set the value of its member variable:
void setValueA(reff& obj, int value)
{
obj.a = value;
}
and then use similar syntax to the getline() method on it:
setValueA(per, 36);
to achieve the same thing as per.a = 36, but with the benefits of encapsulation: if you later need to change the details of how reff stores its data (e.g. changing a and b to meaningful names), you only need to change the function implementation to use the new data members; all user code using this class will continue to work. If user code directly accessed the members, it would also need to be changed to use the new name.
Notice that setValueA() is accessing the member variables of the object it is passed; so calling it with per.a directly is not only unnecessary, but impossible:
setValueA(per.a, 36); // invalid: setValueA() requires a reff&, not an int
since the function itself tries to utilise the member a of the object it is passed, and an int does not have any members.
For the getline() call using a std::string, it has the same issue: for this function to work, it needs at the minimum:
read/write access to a pointer to the memory to store the data it reads (it may need to reallocate this if there's not enough space already allocated); and
the amount of memory pointed to the above, so it knows how much additional data it can store before it needs to allocate additional space.
So, given that getline() requires more than just a single intrinsic type in order to function, it should be clear why the parameter includes a string object rather than one of its specific member variable.
For additional examples, you should look up operator overloading, which can even let you do things like have per = 36; assign a value to per.a.
Here's a self-contained example using overloaded operators on a slightly modified version of your reff class. The comments try to explain what's going on, and should give you terms you can search for - this stuff is all pretty basic C++ and should be covered in any tutorial series.
#include <iostream>
class Reff
{
public:
int a;
float b; // changed the data type to illustrate overloading the = operator
// operator= will be called if we try to assign to a an object of this class;
// this version of the function accepts an integer value
Reff& operator= (int intval)
{
a = intval;
return *this;
}
// another operator=, this one accepting a float value as the parameter
Reff& operator= (float floatval)
{
b = floatval;
return *this;
}
};
// operator+ will be called if we try to add a value to this object;
// I'm only defining this one which accepts an int value
int operator+ (Reff const& reff, int intval)
{
return reff.a + intval;
}
// an overload of the operator<< function, which accepts a reference to
// an instance of a Reff, along with the output stream parameter.
std::ostream& operator<< (std::ostream& stream, Reff const& reff)
{
return stream << "[a:" << reff.a << " b:" << reff.b << "]";
}
int main()
{
// create an instance of our class
Reff per;
// assign the instance 42 (an integer value) - this will use the integer
// overload of the operator= we defined
per = 42;
// assign it a floating point value - this will use the float overload
// of the operator=. Note that if we didn't define a float-specific overload,
// the compiler would probably truncate the value to an integer and use our
// integer version instead - possibly with a warning, possibly silently,
// depending on your compiler settings.
per = 3.14159f;
// output the object; this will use the overload of the operator<< function
// that we created, which accepts our Reff object
std::cout << per << std::endl;
// output the result of adding 58 to our object; this will use the operator+
// overload which accepts an integer
std::cout << "per + 58 = " << (per + 58) << std::endl;
}
Here you can get output directly through
cout << "I like " << mystr << " too!\n";
because operator << is overridden in string Class.
like:
ostream& operator << (ostream& OS, MyString & S)
{
OS << S.get_string();
return OS;
}
Check whole implementation : http://www.cplusplus.com/forum/beginner/15396/
I want to output the values of the private class members Bankcode and AgentName. How can I do this from within my main() function, or in general, outside of the BOURNE class.
My initial code attempts are below:
#include <iostream>
#include <string>
using namespace std;
class BOURNE
{
string Bankcode ={"THE SECRET CODE IS 00071712014"} ; /*private by default*/
string AgentName={"Jason Bourne"}; /*private by default*/
public:
void tryToGetSecretCodeandName(string theName ,string theCode); //trying to get the private
void trytoGetAgentName( string name); // try to get name
};
//***********************defining member function**************************************
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode) //member defining function
{
Bankcode=theCode; //equalling name to the code here
AgentName=theName; //the samething here
cout<<theCode<<"\n"<<theName; //printing out the values
}
//************************main function*****************************
int main()
{
BOURNE justAnyObject; //making an object to the class
justAnyObject.tryToGetSecretCodeandName();
return 0;
}
Third Answer
Your code has two 'getter' style functions, but neither one takes no arguments. That is, both of your functions require arguments to be passed.
Your main function is calling get...CodeandName(), which has no arguments. As such, you get a compiler error, probably complaining about valid signatures, or arguments passed.
Edited Answer
If you only want to get the values, the typical (as far as I am aware) implementation is something like
std::string BOURNE::getCode()
{
return Bankcode;
}
std::string BOURNE::getName()
{
return AgentName;
}
int main()
{
BOURNE myAgent;
cout<< "The agent's name is : " << myAgent.getName() << endl;
cout<< "The agent's code is : " << myAgent.getCode() << endl;
}
Original Answer, left in because I feel like it's more useful
I suspect what you're asking is if you could do something like
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode)
{
if (Bankcode == theCode) {
cout<< "You correctly guessed the code : " << Bankcode << endl;
}
if (AgentName == theName) {
cout << "You correctly guessed the agent's name : " << AgentName << endl;
}
}
This will allow you to repeatedly guess at the name, and get output when you're correct.
If you wanted to disable this kind of guessing, then you could consider creating a new class (possibly derived from/based on std::string - but see this question for reasons to be careful!) and implement an operator== function which always returned false.
I am trying to store a char* into a struct's char* field. I have tried different things but none of them worked. The problematic piece of code is shown below:
pInfo is the object of the struct PlayerInfo.
PlayerInfo *pInfo = (PlayerInfo*)malloc(sizeof(PlayerInfo));
The char* I get from GetAddress is stored in the Address field of PlayerInfo.
pInfo->Address = GetAddress(pInfo->playerId);
The GetAddress function is shown below. It converts integers to strings, stores them in a vector and returns the vector as a char* using &retChar[0].
char* GetAddress(int playerId)
{
std::string strPlayerId = std::to_string(playerId);
std::string strGroupId = std::to_string(group.GetGroupId());
std::string retAddress = strPlayerId + ":" + strGroupId + ":" + GenRandomChar();
//From -- http://stackoverflow.com/questions/347949/convert-stdstring-to-const-char-or-char
std::vector<char> retChar(retAddress.begin(), retAddress.end());
retChar.push_back('\0');
for(std::vector<char>::const_iterator i = retChar.begin(); i != retChar.end(); ++i)
std::cout << "retChar is " << *i << std::endl;
return &retChar[0];
}
When I print the contents, only garbage is printed. I tried printing the memory contents from gdb, but that also did not help.
char* address = GetAddress(pInfo->playerId);
std::cout << "address is " << *address << std::endl;
std::cout << "address is " << pInfo->Address << std::endl;
std::cout << "address is " << *(pInfo->Address) << std::endl;
The problem is, that your function scope local variable
std::vector<char> retChar;
goes out of scope and is destroyed after your function returned.
Thus using the returned pointer return &retChar[0]; is calling undefined behavior.
The better choice would be to pass the pointer where to copy the data as a reference
void GetAddress(int playerId, char*& result) {
std::vector<char> retChar;
// ...
std::copy(retChar.begin(),result);
}
and ensure result buffer is big enough to receive the copied data.
NOTE:
The above suggestion just solves the 1st level of your current problem. The probably better idea is to change your function simply to deal with std::string instead of using std::vector<char> and raw char* pointers (if your use case allows to refactor this):
Make PlayerInfo::Address member a std::string type
struct PlayerInfo {
// ...
std::string Address;
};
and define your GetAddress() function as follows
std::string GetAddress(int playerId) {
std::ostringstream result;
result << playerId << ":" group.GetGroupId() << ":" << GenRandomChar();
return result.str();
}
and use the results std::string::c_str() method if you really need a const char* value to pass it elsewhere.
I think the idea of using std::vector<char> in the selected answer to How to convert a std::string to const char* or char*? is that the std::vector<char> is your writable character array, not that you should extract a char * from it. (You can, however, copy the contents into a different memory location identified by a char *, as you have already seen.)
But I would ask why you are storing a char * in the Address member of PlayerInfo. Why don't you make that member an std::string and change the return type of getAddress() to std::string, in which case getAddress can simply return retAddress?
Alternatively, you can declare getAddress like this: void getAddress(int playerId, std::string& retAddress) and the code inside the function is even simpler, because you don't have to declare retAddress as a local variable inside the function.
void outputString(const string &ss) {
cout << "outputString(const string& ) " + ss << endl;
}
void outputString(const string ss) {
cout << "outputString(const string ) " + ss << endl;
}
int main(void) {
//! outputString("ambigiousmethod");
const string constStr = "ambigiousmethod2";
//! outputString(constStr);
} ///:~
How to make distinct call?
EDIT: This piece of code could be compiled with g++ and MSVC.
thanks.
C++ does not allow you to overload functions where the only difference in the function signature is that one takes an object and another takes reference to an object. So something like:
void foo(int);
and
void foo(int&);
is not allowed.
You need to change the number and/or the type of the parameter.
In your case the function that accepts a reference, you can make it accept a pointer, if you want to allow the function to change its argument.
You could change the signature of one of the methods. It may not look pretty, however it is the simplest way.
So you could in principle have
void outputString(const string &ss, int notneeded) {
cout << "outputString(const string& ) " + ss << endl;
}
void outputString(const string ss) {
cout << "outputString(const string ) " + ss << endl;
}
and when you want to call the first function just call it with:
outputString("ambigiousmethod", 0);
which will result in a distinguishing call.
There is no other way (I'd love to be proven wrong on this one) since C++ does not allow overloading where passing (by value or by reference) is the only difference in signature.
Edit: as pointed out by bzabhi, you could also change the signature by changing the reference to a pointer. In the example you gave that would work, however you may have to change function code on some occasions.
According to your code, u need only
void outputString(const string &ss).
Because both methods cannot change the argument to the caller (because it's const reference or by-value passing).
Why do you need those 2 methods?
I recommend using the techinque of giving each and every function a unique name., i.e., do not use syntax overloading. I have been using it for years and I've only found advantages in it.