How to Return a String From a Function in C++

Jinku Hu Feb 12, 2024
  1. C++ Return String by Value
  2. Returning a String by Reference
  3. Returning a String by Pointer
  4. Use std::move to Return String From Function in C++
  5. Use the char *func() Notation to Return String From Function in C++
How to Return a String From a Function in C++

Returning a string from a function is a common and fundamental aspect of C++ programming. This process is essential for designing flexible and modular code, allowing functions to generate or manipulate strings and pass them back to the calling code.

In C++, developers have various methods to accomplish this task, each with its advantages and considerations. Whether by value, reference, pointer, or utilizing features like std::move, the choice of technique depends on factors such as performance requirements, memory efficiency, and the desired level of control over string manipulation.

In this exploration, we will delve into these different methods, providing comprehensive examples and insights to guide programmers in making informed decisions when returning strings from functions in C++.

C++ Return String by Value

One of the simplest ways to return a string from a function is by returning it as a value. This involves creating a local string variable within the function, populating it with the desired content, and then returning it.

Return by the value is the preferred method for returning string objects from functions. Since the std::string class has the move constructor, returning even the long strings by value is efficient.

If an object has a move constructor, it’s said to be characterized by move semantics. Move-semantics imply that the object is not copied to a different location on function return, thus providing faster function execution time.

In C++, returning a string by value involves creating a local string variable within a function, populating it with the desired content, and then returning it. This method is straightforward and often used when the string’s size is manageable and efficient copying is not a concern.

#include <iostream>
#include <string>

std::string returnStringByValue() {
  std::string result = "Hello World!";
  return result;
}

int main() {
  std::string returnedString = returnStringByValue();
  std::cout << returnedString << std::endl;
  return 0;
}

Output:

return string by value

The code above declares a function named returnStringByValue that returns a std::string object. This function creates a local string variable, initializes it with the value "Hello World!", and then returns it.

The returned string is assigned to returnedString in the main function and subsequently printed.

Returning a String by Reference

This method uses return-by-reference notation, which can be an alternative approach to this problem. Even though return by reference is the most efficient way to return large structures or classes, it would not impose extra overhead compared to the previous method in this case.

Returning a string by reference involves passing a reference to the original string to the calling function, avoiding the creation of a new string copy. This can be advantageous when working with large strings or when the goal is to modify the original string directly within the function.

#include <iostream>
#include <string>

const std::string& returnStringByReference(const std::string& s) {
  // Some processing
  return s;
}

int main() {
  std::string originalString = "Hello, World!";
  const std::string& returnedString = returnStringByReference(originalString);

  // The returnedString is a reference to the original string
  std::cout << returnedString << std::endl;

  return 0;
}

Output:

return string by reference

In the code above, returnStringByReference takes a const reference to the original string, performs some processing (which can include modification of the string), and returns the same reference.

Returning a String by Pointer

Returning a string by pointer involves dynamically allocating memory for the string within the function and returning a pointer to the allocated memory. This allows for efficient resource management and is particularly useful when working with large strings or when the goal is to create and return a new string.

#include <iostream>
#include <string>

std::string* returnStringByPointer() {
  std::string* result = new std::string("Hello World!");
  return result;
}

int main() {
  std::string* returnedString = returnStringByPointer();

  // Access the string through the pointer
  std::cout << *returnedString << std::endl;

  // Remember to free allocated memory
  delete returnedString;

  return 0;
}

Output:

return string by pointer

In this code, returnStringByPointer dynamically allocates memory for a new string, initializes it with the value "Hello World!", and returns a pointer to the allocated memory.

Use std::move to Return String From Function in C++

Introduced in C++11, std::move is a utility function that transforms an object into an rvalue, enabling the efficient transfer of ownership or resources.

When applied to a string, std::move allows for the movement of the string’s internal data rather than a costly deep copy. This is particularly useful when returning strings from functions, minimizing unnecessary overhead.

#include <iostream>
#include <string>

std::string returnStringByMove() {
  std::string result = "Hello, Efficient World!";
  return std::move(result);
}

int main() {
  std::string returnedString = returnStringByMove();
  std::cout << returnedString << std::endl;
  return 0;
}

Output:

return string using std move

In this program, std::move is employed within the returnStringByMove function to signal that the ownership of the string should be transferred efficiently.

Use the char *func() Notation to Return String From Function in C++

We can use the char* notation to return a string from a function in C++. However, there are a few important considerations and potential pitfalls to be aware of when using this approach.

In C++, strings are often represented using the std::string class, which provides a more convenient and safer way to handle strings compared to traditional C-style strings (char*). The std::string class automatically manages memory and provides various string manipulation functions, making it less error-prone.

That said, if you have specific reasons to use C-style strings, you can return a char* from a function. Here’s a basic example:

#include <cstring>
#include <iostream>

const char* returnCString() {
  const char* result = "Hello, C-Style String!";
  return result;
}

int main() {
  const char* returnedCString = returnCString();
  std::cout << returnedCString << std::endl;
  return 0;
}

Output:

return string using char

In this example, the returnCString function returns a pointer to a constant character array (C-style string). The calling code then prints the C-style string using std::cout.

The C-style string is a string literal, and the compiler manages its memory. Returning pointers to string literals is safe, but if you dynamically allocate memory for a C-style string within the function using new, the caller becomes responsible for freeing that memory using delete.

While using char* is a valid option, it’s recommended to consider using std::string for most string-related tasks in modern C++ due to its safety, convenience, and additional functionality. If you have specific use cases where C-style strings are required, ensure that you handle memory management carefully to avoid potential issues.

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C++ String