C++ - syntax for defining/instantiating strings - c++

I am very new to C++ and still trying to learn syntax and best practices.
I've defined a method with a single parameter:
void foo(const std::string& name)
1) Is this a proper parameter declaration for a function that will be taking in a string defined by the user in, for example, a main method?
2) If this is proper/recommended syntax, what would an instantiation of a sample parameter look like?

Yes, that is the correct syntax. You can call it and provide parameters several different ways:
With a string literal:
foo("bar");
With a string variable:
std::string b = "bar";
foo(b);
With the result of a function return type string:
std::string quux();
foo(quux());
With a char* variable:
int main(int argc, char const* argv[]) {
foo(argv[0]);
}

I'm not sure if I fully understand your question, but I'll try to clarify it.
You use the terminology 'method'. I'm assuming that your method is encapsulated in a class? If so, then :-
In your header file (eg. source.h),
class dog
{
...
public:
void foo(const std::string &name);
...
};
In your source file (eg. source.cpp)
void dog::foo(const std::string &name)
{
// Do something with 'name' in here
std::string temp = name + " is OK!";
}
In your 'main' function, you can instantiate your 'dog' class, and call the 'foo' function like :-
void blah()
{
dog my_class;
my_class.foo("Testing my class");
}
If you want a function (ie. a 'method' that is not encapsulated within a class), then what you have is correct.
In your source file (eg. source.cpp)
void foo(const std::string &name)
{
// Do something with 'name' in here
std::string temp = name + " is OK!";
}
If you want to be able to call your function from outside that particular source file, you'll also need to forward declare your function in a header file.
In your header file (eg. source.h)
void foo(const std::string &name);
To call your function,
void blah()
{
foo("Testing my class");
}
Hope this helps!

1)
It is a proper parameter declaration if function foo() doesn't mean to change the string. The 'const' keyword is used to signify that the string won't be changed by the receiver.
If you write code in foo() which modifies the string you will get compiler error/warning.
2)
std::string theString = "Hello";
foo( theString );

Is this a proper parameter declaration for a function that will be taking in a string defined by the user in, for example, a main method?
Yes.
#include <string>
using namespace std;
void foo(const string& name)

1) Yes, that's a very good way to do it if you only need to read the string in the function.
2) There is no instantiation going on?

1) For most functions, it would be a fine signature. However, since you mentioned main(), there are only two valid signatures:
int main()
int main(int argc, const char* argv[])
...as you can see, you have to use C-style strings due to C-legacy compatibility (and efficiency)
2) Not sure I understand your second question, but since std::string has a constructor that takes a const char*, you can just say:
foo("hello");
or:
std::string input;
std::cout << "Enter some text: ";
std::cin >> input;
foo(input);

Related

How to overload an in-place and a copying string manipulation functions?

I would like to be able to do the following:
std::cout << str_manip("string to manipulate");
as well as
std::string str;
str_manip(str);
std::cout << str;
For this, I have two functions
#include <string>
// copying
std::string str_manip(std::string str)
{
// manipulate str
return str;
}
// in-place
void str_manip(std::string& str)
{
// manipulate str
}
but they produce the following error:
error: call of overloaded 'str_manip(std::__cxx11::string&)' is ambiguous
How can I overcome this?
The problem is with this call:
std::string str;
str_manip(str);
std::cout << str;
The compiler doesn't know which version of str_manip to call.
You can change your functions to look like this:
#include <string>
// copying
std::string str_manip(const std::string& str)
{
std::string dup = str;
// manipulate dup
return dup;
}
// in-place
void str_manip(std::string& str)
{
// manipulate str
}
Now, the compiler knows that the ambiguous call has to be the function that takes the non-const parameter. You can also be sure that your call that returns a std::string to the << operator isn't modifying your string.
This might be not the thing you are looking for, but for your code
std::cout << str_manip("string to manipulate");
the parameter to str_manip is not a string but const char* (actually an array, but convertible to a char pointer). You can overload based on that.
std::string str_manip(const char* s)
{
std::string str(s); // create str
// manipulate str
return str;
}
However, let's look at the big picture. When you see str_manip in your code, does this mean "change the string" or "make a new string based on the given string"? Do you want to be intentionally ambivalent on the real meaning?
Consider yourself reading your code in 1 year in future. What will you think when you see a call to str_manip - does this mutate its parameter? Does the answer to the previous question depend on context?
The goal in writing code is to make it clear, especially in a multi-paradigm language like C++. So, in my opinion, just don't do overloading that you are thinking about. Instead, make 2 distinct names, like
void frobnicate_str(std::string&) {...}
std::string get_frobnicated_str(std::string) {...}

How do I print a variable from main with a function in a class, Help understanding OOP c++

Section 9(1/4) out of 11 of my c++ introduction webclass;
I have no idea what I'm doing.
I'm unsure even of what terms to search for(first touch with OOP).
-
I need to print the cin in main with a function in a class,
So far I have come up with a class with a string variable and a function that do nothing;
#include <iostream>
#include <string>
using namespace std;
class printclass
{
public:
string array;
void print();
};
void printclass::print()
{
cout << array;
}
Main program(cannot be edited);
int main()
{
char array[50];
cout << "Enter string:";
cin.get(array, 50);
printclass printer;
printer.print(array);
}
It is my understanding that the printclass printer; creates an object 'printer' with the printclass class and thus knows how to use the functions in the class
on sort-of a blank page that is declared with the call, am I far off?
How do I print the value of the array in main with the function?
The exercise has been translated from finnish, please excuse blunt grammar and user stupidity.
Thank you for your time!
am I far off?
Kinda. You've incorrectly assumed the interface of your printclass. Here's a correct one1 from the example posted:
class printclass {
public:
printclass();
void print(const char* str);
};
From that it's quite easy to spot your mistake; you've assumed that your class has to store the array to print, while the interface passes it directly. It's enough to implement the print in terms of str without any member variables:
void printclass::print(const char* str) { // could be const
std::cout << str;
}
Note: the constructor can of course be left alone and it will default to what you want.
1One of many possible interfaces, but I've picked the most likely.

Passing strings by reference and value in C++

I want to declare a string, initialize it by passing it by reference, and then pass it by value to the 'outputfile' function.
The code below works, but I don't know why. In main I would expect to pass the string 'filename' like
startup(&filename)
But that gives an error, and the code below doesn't. Why? Also, is there a better way to do this without using a return value?
#include <iostream>
#include <string>
using namespace std;
void startup(std::string&);
void outputfile(std::string);
int main()
{
std::string filename;
startup(filename);
outputfile(filename);
}
void startup(std::string& name)
{
cin >> name;
}
void outputfile(std::string name)
{
cout << name;
}
Your code works as expected.
&filename returns the memory address of (aka a pointer to) filename, but startup(std::string& name) wants a reference, not a pointer.
References in C++ are simply passed with the normal "pass-by-value" syntax:
startup(filename) takes filename by reference.
If you modified the startup function to take a pointer to an std::string instead:
void startup(std::string* name)
then you would pass it using the address-of operator:
startup(&filename)
As a side note, you should also make the outputfile function take its parameter by reference, because there's no need to copy the string. And since you're not modifying the parameter, you should take it as a const reference:
void outputfile(const std::string& name)
For more info, here are the rules of thumb for C++ regarding how to pass function parameters.

Variable name as a string data member

In C++ is it possible to declare a class which has a private std::string data member which is initialized with the stringized / stringified name of the instance symbol name? I can see that this couldn't work for temporaries, but for lvalues is it possible?
Here is what I would like:
#include <iostream>
#include <string>
class symbol {
public:
symbol() { // here goes some magical sauce }
void print() { std::cout << s_ << std::endl; }
private:
std::string s_;
};
int main() {
symbol bar, bah;
bar.print() // should print "bar" to STDOUT
bah.print() // should print "bah" to STDOUT
}
If I were to change the constructor to accept a string and introduce a preprocessor macro, then I can almost get what I want, but it smells bad.
#define makesymbol(x) foo x(#x)
symbol(const std::string & s) : s_(s) {}
// Now I can do:
makesymbol(test);
test.print(); // <--- This prints "test" followed by a newline to STDOUT
Basically what I would like to avoid is for the user to have to declare instances of symbols like:
symbol phi("phi");
Because it is annoying to read, annoying to type, and redundant. I can see why in some cases you might want a different string stored than the variable name, but I'm specifically trying to the solve the problem where you know you want the string to be equal to the stringized variable name.

c++ .h and .cpp files - about methods

HI.
How can I define a bool method in .h file and work with it in the cpp file?
I have
my.h
#include <string>
public class me;
class me
{
public:
me();
private bool method(string name); //it is ok??
}
my.cpp
#include 'my.h';
me::me()
{
method(string name); //can i do this? isn't there another alternative?
}
method (String name)
{
cout<<"name"<<endl;
}
is not working.why?
I suggest you learn the basics of C++ from a tutorial
my.h
#include <string>
class me
{
public:
me();
bool method(std::string name) const;
};
my.cpp
#include 'my.h';
me::me()
{
}
bool me::method(std::string name)
{
std::cout << name << std::endl;
}
As written, there is no need for me::method to be a member function (it could be a static).
Numerous little fixes there. I get the sense that you are coming from C# (possibly java). Read up on the differences. Google has good sources :)
There are a number of issues with your code.
my.h
#include <string>
// public class me; // Absolutely not needed. From which language did you get this?
class me
{
public:
me();
private: // You need the colon here.
bool method(string name); //it is ok?? // No. The class is called std::string. You should pass it by const-reference (const std::string& name);
}
my.cpp
#include 'my.h';
me::me()
{
// `name` is undefined here. You also don't need to specify the type.
//method(string name); //can i do this? isn't there another alternative?
method("earl");
}
// method (String name) // See previous comment about const-reference and the name of the class. Also note that C++ is case-sensitive. You also need to specify the return type and the class name:
bool me::method(const std::string& name)
{
// cout<<"name"<<endl; // Close...
std::cout << "My name is " << name << std::endl;
return true; // we are returning a `bool, right?
}
You'll also need to call your code:
int main()
{
me instance_of_me;
return 0;
}
I suggest you take a look for a good C++ tutorial and some reading material.
Answers to questions in the comments:
could you please tell me why do I need to pass std::string through reference?
This question has already been asked (more than once) on StackOverflow. I recommend this answer.
And what is with me mo?
In hindsight mo was a terrible choice for a variable name. instance_of_me may have been a better choice. This line constructs an instance of me, calling the constructor (which in turn calls method("earl"))
You meant me method("hello"); in the main()
I certainly did not!
You declared method as a private member function. This method cannot, therefore, be called from outside the class.
First of all, you have missed : after private
Second, if method (String name) in the cpp file should be the method (String name) from your class, it must be:
bool me::method(std::string name)
{
// ...
}
Third, if you want this bool me::method(std::string name) to be different function, a global one, not from you class, it must be:
ret_type method(std::string name)
{
// ...
}
And, fourth,
cout<<"name"<<endl;
will pring the string (literal) "name". If you want to print the variable name, use it without the quotes:
std::cout<< name <<endl;
I'd recommend you to get a book
Ah, and this one:
me::me()
{
method(string name); //can i do this? isn't there another alternative?
}
method(string name) - this is not valid syntax. It should be something like:
me::me()
{
string name;
// do something with name
method( name ); // if "method" is a method, for real
}