Adding const-ness after the fact in C++ [duplicate] - c++

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Is there some ninja trick to make a variable constant after its declaration?
Consider the following minimal example:
void MutateData(std::string&);
int main()
{
std::string data = "something that makes sense to humans.";
::MutateData(data); // Mutates 'data' -- e.g., only changes the order of the characters.
// At this point, 'data' should never be changed.
// Mixing the above with const-correct code seems ugly.
}
Currently, I'm doing:
namespace
{
std::string PrepareData(std::string data)
{
::MutateData(data);
return data;
}
}
int main()
{
const std::string data = ::PrepareData("something that makes sense to humans.");
}
What are some elegant solutions to simulating const beyond the point of declaration?
EDIT: I forgot to clarify that I can't easily (not my code) change MutateData.

You can use a const reference.
Take a look at http://herbsutter.com/2008 for an explanation about why it works.

What about:
string MakeData(string const&)
{
...
return string(...); // for return value optimization
}
followed by
int main()
{
string const& str = MakeData("Something that makes sense to humans");
}
The difference with what you do is using a const reference, and only one function. If you cannot change MutateData, do what you suggested (with the const reference though)

Related

does returning const int from a function make any sense in C++? [duplicate]

This question already has answers here:
What are the use cases for having a function return by const value for non-builtin type?
(4 answers)
Should I return const objects?
(12 answers)
Closed 5 months ago.
This post was edited and submitted for review 5 months ago and failed to reopen the post:
Duplicate This question has been answered, is not unique, and doesn’t differentiate itself from another question.
I understand for pointers and objects making them const while returning returns a locked copy of that object so like for objects only const functions can be called on it.
I was wondering is there any sense in returning const int from a function. Since int is just a primitive type I don't see any difference between: const int& myFunction(); and int& myFunction();.
Is there any small difference between the two that I am missing here or are they EXACTLY the same and therefore writing const before int& return type is just stupid?
Edit:
#include <vector>
const int& getConstInt() { return 1; }
int& getInt() { return 1; }
std::vector<int> getSimpleVector() { return std::vector<int>(); }
const std::vector<int> getConstVector() { return std::vector<int>(); }
int main() {
int constInt = getConstInt();
int simpleInt = getInt();
constInt = 2; // does not matter that the return type was const
simpleInt = 2;
std::vector changedAfterReturn = getConstVector().push_back(3); //locked, gives error
changedAfterReturn = getSimpleVector().push_back(3); //not locked... works fine.
getInt() = 2; // This never made any sense in the first place since int is a primitive value.
getConstInt() = 2; // Neither does this. So whats the use in declaring const.
return 0;
}
Updated the question to ask for difference between return value of int& vs const int& instead of return by values.

c++ oop program doesn't give expected result [duplicate]

This question already has answers here:
Returning a reference to a local variable in C++
(3 answers)
Closed 6 years ago.
Consider the following piece of program:
class cls
{
int vi;
public:
cls(int v=37)
{
vi=v;
}
friend int& f(cls);
};
int& f(cls c)
{
return c.vi;
}
int main()
{
const cls d(15);
f(d)=8;
cout<<f(d);
return 0;
}
When I run it, the output is
15
but I don't understand why 15, because I thought it should've outputed 8, because of the
f(d)=8
function, which from what I understand makes the c.vi=8, but I might be wrong and the function probably does something else entirely, so then I ask, what is the purpose or what does the
friend int& f(cls);
function do?
Your program has Undefined Behavior - you are returning a dangling reference to local variable of a function (argument is a local variable as well).

C++ Programming ( advantages of by ref & by val) query? / methods of editing struct other than byRef

I am going over a mock exam in revision for my test, and one question on the paper confuses me.
Q.)An application is required to pass a structure to a function, which will modify the contents of the structure such that on return from the function call the caller can use the new structure values. Would you pass the structure to the function by value, address or reference?
State clearly why you chose a particular method. Justify your choice by comparing the three methods.
Now I have difficulty understanding this, because I assume the best answer to the question would always be by Ref as that takes the reference pointer of the value and edits its contents rather than just getting a copy. This would be different if using a class based program.
The only other method I would understand would be having a separate value and getting and setting the values, but this would mean extra lines of code, I am a little unsure on what this means, can anyone help enlighten me ? I do not know any other methods to achieve this.
This is not "advanced programming"; it is the absolute basics of C++.
Whether return-by-value or "out" parameters (implementing using references or pointers) are "best" for any given use case depends on a number of factors, style and opinion being but two of them.
// Return by value
// T a; a = foo(a);
T foo(const T& in) // or: T foo(T in)
{ // {
T out = in; //
out.x = y; // in.x = y;
return out; // return in;
} // }
// Out parameter (reference)
// T a; foo(a);
void bar(T& in)
{
in.x = y;
}
// Out parameter (pointer)
// T a; foo(&a);
void baz(T* in)
{
in->x = y;
}
The question is asking you what the pros and cons are of these three approaches.

Improving the efficiency of the most trivial C++ program [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
A brother suggested me that I pass the arguments in the constructor and other member functions of the class by reference instead and even return references from member functions, so that it avoids copying of variables all the time. I'm a very naive programmer and don't know how best to do it. Can you please tell me how to apply it to the following program:
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
Student(string s, int i) {
name = s;
id = i;
}
void setName(string s) {
name = s;
}
void setId(int i) {
id = i;
}
string getName() {
return name;
}
int returnId() {
return id;
}
private:
string name;
int id;
};
int main() {
Student s1("Seth",515);
}
This is what I did:
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
Student(string& s, int& i) {
name = s;
id = i;
}
void setName(string& s) {
name = s;
}
void setId(int& i) {
id = i;
}
string& getName() {
return name;
}
int& returnId() {
return id;
}
private:
string name;
int id;
};
int main() {
string s = "John";
int i = 515;
Student s1(s,i);
return 0;
}
Is it alright to return reference variables, I mean don't they go out of scope in some cases?
I'm agree with Alexander completely: first, in your program it won't probably give you anything. Second, premature optimization is the root of all evil.
Still, if you're interested, in general passing a value by reference usually looks like this:
void myFunction(const MyComplicatedClass& argument) {...}
Here argument is passed as a reference to a constant object. This means that:
Instead of passing a value to the function, we pass a reference, so our function, when it accesses argument, will, in essence, work with the same region of memory as the function, that called myFunction. BUT if it works with the same region of memory, it can mess it up. So
We pass a reference to a constant object. It means, that the compiler will ensure, that we don't do anything, that can mess up the original object (which was passed to us asargument). It's not a 100% guarantee, we are talking about C++, it's relatively easy to shoot in the foot here, but the compiler will try his best :)
But it's important to understand, that there is no point in using this approach everywhere. For instance, there is no point in passing int value as a const reference, since it is a primitive type already. You might even make things less efficient. Many classes are implemented in a way, that makes copying a very cheap operation. And, finally, compilers nowadays are very smart. They can optimize out many things that you didn't think of.
Still, I don't say that this is useless. As with every tool, you should understand, how it works and when to use it. It comes with experience and studying.
As for returning a reference, never return a reference to local variables. They get deleted the moment they go out of scope, and your program will crash when you'll try to access a reference to a deleted content. You can, however, return references (const references) to anything, that you're sure will live long enough. For instance, class fields.

Trying to understand how to return references to automatic variables [duplicate]

This question already has answers here:
Returning a reference to a local variable in C++
(3 answers)
Closed 8 years ago.
I'm trying to understand why the second piece of code compiles fine, given that the first doesn't.
int & test(void) {
int v = 0;
return v;
}
int main(void){
int & r = test();
return 0;
}
I understand that this doesn't work because you can't pass a reference to an automatic variable that will be deleted. It seems to me that the code below should have the same problem but it doesn't.
int & test1(int & x) {
return x;
}
int & test2(void) {
int x = 0;
return test1(x);
}
int main(void){
int & r = test2();
return 0;
}
Seems like the intermediate function is solving the problem. But why?
Just because something compiles, doesn't mean it works...
The two "alternatives" both suffer from the same exact problem; r, in main, is a dangling reference, what it refers to is long gone, and using it will lead to undefined behavior.
1st snippet
In the first example it's easy enough for the compiler to see that you are returning a reference to a local variable, which (as compilers know) doesn't make any sense.. the referred to instance will be dead when the reference reach main.
The compiler is being a good champ and tells you about the issue.
2nd snippet
In the second example you are doing the same thing, but adding a redirection in-between. A compiler got many tricks up its sleeve, but back-tracing every possible execution path to see if a developer is returning a reference to a local variable, by indirection, isn't one of them.
The compiler can't see that you are being bad, and it cannot warn you about issues it doesn't know about.
Conclusion
Returning a reference to a local variable is bad, no matter how you do it.
Think about what the compiler would have to do to catch the problem you're demonstrating. It would have to look at all callers of test1 to see whether they're passing it a local. Perhaps easy enough, but what if you insert more and more intermediate functions?
int & test1(int & x) {
return x;
}
int & test2(int & x) {
return test1(x);
}
int & test3() {
int x = 0;
return test2(x);
}
int main(void){
int & r = test3();
return r;
}
The compiler would have to look not only at all callers of test1, but then also all callers of test2. It would also have to work through test2 (imagine that it's more complex than the example here) to see whether it's passing any of its own locals to test1. Extrapolate that to a truly complex piece of code--keeping track of that sort of thing would be prohibitively complex. The compiler can only do so much to protect us from ourselves.
The both code examples are ill-formed and have undefined behaviour because local objects will be deleted after exiting the functions. So the references will be invalid.
To understand that the second example does not differ from the first example you could rewrite it the following way (insetad of calling the second function)
/*
int & test1(int & x) {
return x;
}
*/
int & test2(void) {
int x = 0;
/* return test1(x);*/
int &r = x;
return r;
}
As you see there is no any difference between the examples.
To achieve what you want you could the following way
int test()
{
int v = 0;
return v;
}
int main()
{
const int & r = test();
return 0;
}