I have a class that holds data that I expect to use a lot, so I thought it would be best to return a const reference to it. However, given some parameters, I might need to create new data on the fly. I've seen that you can return a temporary to a constant reference like so:
class Foo {
public:
Foo() { ... } //Initialize data
LARGE_DATA getData(bool param1, bool param2) {
if (...) { // For some crazy function of the parameters
LARGE_DATA newData = ...; // Create new data and return it
return newData
}
return data; // Usually, will just use the default value
}
private:
LARGE_DATA data;
};
void bar() {
Foo f;
const LARGE_DATA& data = f.getData();
... // Process data (read-only)
}
but this seems like it would make a copy of data. I would like to do something like this:
class Foo {
public:
Foo() { ... } //Initialize data
const LARGE_DATA& getData(bool param1, bool param2) {
if (...) { // For some crazy function of the parameters
LARGE_DATA newData = ...; // Create new data and return it
return newData
}
return data; // Usually, will just use the default value
}
private:
LARGE_DATA data;
};
void bar() {
Foo f;
const LARGE_DATA& data = f.getData();
... // Process data (read-only)
}
so to avoid unnecessary copies. Visual Studio doesn't complain about this, but g++ does (and probably rightly so). What's the right way to do this?
I think I understand your dilemma. In your first implementation, you're relying on a feature of C++ described here where a temporary (newData in this case) returned from a function has its lifetime extended when a const reference to it is saved on stack by the calling function. But if data is returned instead of newData, it will create a copy and then return the copy as a temporary, which you don't want.
Your second implementation attempts to prevent making a copy of data by returning a reference, but this breaks with g++ because of newData. You are no longer returning a temporary object called newData, you are now returning a reference to it, which doesn't qualify for lifetime extension according to g++.
I see two ways out of this. You can either break getData() into two methods, one which will return data by returning a reference, and another which returns newData by value so a temp is created. Or you could save newData as a data member of the class, return a reference to that as you would to data, and let it be overwritten each time you need to recalculate it, which however only works if you only need to read a given value of newData between consecutive calls to getData().
You should probably either retain ownership by storing newData somewhere in Foo before returning a reference to it (maybe in a map that you lazily initialize where the key is a representation of the function arguments, like std::pair<bool, bool> in this case), or use some reference counted smart pointer (boost::shared_ptr/std::shared_ptr in C++11) to hold the newData if you don't want to retain ownership (also wrapping the data member in a smart pointer).
To me, it seems like a use-case for pointers.
Have the method getData return a pointer and if you don't want the returned object to be modified, have it return a const pointer. What the pointer points to - the member data or the temporary data you create on the fly - can be decided at runtime. This would also avoid copying of the data when the method returns.
In this approach, one thing you need to be cautious of is that the temporary data that you create would have to be on heap, otherwise the returned pointer will point to memory that is out of scope.
Related
I have a class in which I would like one of the functions to pass a unique ptr object to a char array. But I'm confused on several on features of unique pointers. I'm aware a destructor is called automatically when there are no more references to the object but is still the same for primitive variables? For instance if I do this, will the memory be deleted?
class A {
private:
public:
A(std::unique_ptr<char[]> data) {
data = nullptr;
}
~A();
};
int main() {
auto data = std::make_unique<char[]>(10);
A a(std::move(data));
return 0;
}
The next question I have is: If I have a private object which I want to point to data, why does this result in a compiler error?
class A {
private:
std::unique_ptr<char[]> internaldata;
public:
A(std::unique_ptr<char[]> data) {
internaldata = data;
}
~A() {
internaldata = nullptr;
}
};
int main() {
auto data = std::make_unique<char[]>(10);
A a(std::move(data));
return 0;
}
However when I call std::move while assigning it, the code compiles fine.
class A {
private:
std::unique_ptr<char[]> internaldata;
public:
A(std::unique_ptr<char[]> data) {
internaldata = std::move(data);
}
~A() {
internaldata = nullptr;
}
};
int main() {
auto data = std::make_unique<char[]>(10);
A a(std::move(data));
return 0;
}
But why do I have to call std::move twice here? Once for passing the argument then the second for assigning? And what exactly occurs in terms of reference count during that process, does a reallocation, copy and deletion occur?
And finally, is it possible to pass data into the smart pointer during the deceleration? Because currently I do it like this:
auto data = std::make_unique<char[]>(10);
char* buf = data.get();
strcpy(buf, "hello\0");
But is it possible to do something along the lines of:
char hellobuffer[] = "hello";
auto data = std::make_unique<char[]>(hellobuffer);
Where data is automatically assigned the correct size needed to store hellobuffer and copies over the data itself?
I'm aware a destructor is called automatically when there are no more references to the object but is still the same for primitive variables?
The destructor is always logically called. However, since things like int and char are trivially-destructible, the compiler understands that nothing should actually get called.
For instance if I do this, will the memory be deleted?
Yes -- the whole point of std::unique_ptr<T> is that your memory is taken care of automatically.
A(std::unique_ptr<char[]> data) {
internaldata = data;
}
That example fails to compile because internaldata = data is calling the copy-assignment operator and copying std::unique_ptr instances is disallowed (hence the unique bit).
And what exactly occurs in terms of reference count during that process, does a reallocation, copy and deletion occur?
There is no reference count -- a std::unique_ptr either refers to something or it is empty. When you std::move from a std::unique_ptr, the moved-from variable becomes empty. If you are looking for a reference-counted pointer type, see std::shared_ptr<T>.
And finally, is it possible to pass data into the smart pointer during the deceleration?
No. For std::make_unique<T[]>, you are only allowed to pass a std::size_t (see overload 2). It should be easy to write a wrapper function for what you are looking for.
So say I was using this to create an object:
MyClass myObject;
and I had the function inside of the class to act upon the object. So one way could be using parameters, like this:
MyClass foo(MyClass a) {
return a;
}
Seems simple. But is there a way so I can use myObject.foo() and it would still return a even though I'm not using it as a parameter? One example could be some of the methods in std::string - you can use std::string.swap(), using the object for the swap() function.
Is there a way, or am I being stupid?
First off, keep in mind that you original code of
MyClass foo(MyClass a) {
return a;
}
does not actually return a. It returns a copy of a, which itself is a copy of whatever instance of MyClass you passed into foo. If you want to pass in a given object, act on it and return it, you need to use references, like so
MyClass & foo(MyClass & a) {
return a;
}
This will ensure that the a you get back from a call to foo is the exact same object you passed into it.
Additionally, an object can always return a reference to itself in one of its members...
class MyClass {
MyClass & foo() { return *this; }
}
This is especially useful in classes where you might want to chain a large number of operations together...
MyClass my = MyClass().foo().bar("Hello").baz(5);
Inside every member function is a magic secret parameter, which is a pointer to the object who's method was called, and the parameter's name is this.
MyClass& foo() { //returns reference to existing MyClass instead of making copies
this->print(); //call a different member
return *this; //return a reference to itself. Common for `operator=` and such.
}
Inside a class's (non-static) member function, you can use *this to name the object the function was called on.
So:
MyClass MyClass::foo() {
return *this;
}
(Notice that function returns a copy of the object. If you don't want a copy, use a reference as in #Jherico's answer.)
I have edited this from my real code, so that it is a little easier to understand.
The base class:
class MWTypes
{
public:
virtual long get() { return (0); }
};
The derived class: (There are going to be other classes like char, double etc etc . . .)
class TypeLong : public MWTypes
{
public:
TypeLong(long& ref) : m_long(ref) {}
~TypeLong();
long get() { return m_long; }
private:
long& m_long;
};
and the storage class:
class RowSet
{
public:
void addElememnt(MWTypes elem);
MWTypes getElement();
std::vector<MWTypes> getVector() { return m_row; }
private:
std::vector<MWTypes> m_row;
};
How it is called:
for (i = 0; i < NumCols; i++) // NumCols is 3 on this instance
{
switch(CTypeArray[i]) // this is an int which identifies the type
{
case SQL_INTEGER:
{
long _long = 0;
TypeLong longObj(_long);
MWTypes *ptr = &longObj;
// some SQL code goes here that changes the value of _long,
// there is no need to include it, so this will do.
_long++;
// I now want to save the data in a vector to be returned to the user.
rowSet.addElememnt(*ptr);
///////////////////////////////////////////////
// some code happens here that is irrelevant //
///////////////////////////////////////////////
// I now want to return the typr I have saved in the vector,
// I THINK I am doing this right?
MWTypes returned = rowSet.getElement();
// lastly I want to get the value in the returned type
long foo = returned.get();
///////////////////////////////////////////////
// some code happens here that is irrelevant //
///////////////////////////////////////////////
I think I am on the right lines here. The value of 'foo' is always 0. I have a feeling this could be the way Im storing in the vector, or it could be the base virtual function, as it always returns 0.
If I remove the return in my base class I get LNK2001 errors.
MWTypes returned = rowSet.getElement();
// lastly I want to get the value in the returned type
long foo = returned.get();
should be
MWTypes* returned = &rowSet.getElement();
// lastly I want to get the value in the returned type
long foo = returned->get();
or
MWTypes& returned = rowSet.getElement(); // actually illegal, but MSVC will let you do
// lastly I want to get the value in the returned type
long foo = returned.get();
Indeed, polymorphic calls must be made via a pointer or a reference.
EDIT: this is not your only problem. The fact that the vector stores objects (and not pointers) will slice the objects and destroy their type information.
See this faq entry for additional info to help you solve your problem and understand how virtual functions are called.
The fundamental problem is that you are making copies of your objects of type MWTypes, thus losing their particular subclass. If you want to use an object of an unknown subclass of the base class, then you can only use a pointer or reference to the base type, not an actual instance of it.
Not providing an implementation of the function "get" as ascanio's code shows (making the function "pure virtual") would prevent you from being able to make this copying mistake, because the compiler would not let you instantiate the class MWTypes if you did that (it would say the class is "abstract").
You are suffering from slicing since your collection stores copies of the base type. Whenever you store something into the vector, your code just slices off the base part and it forgets its original type.
To fix this, you could store pointers to the base: std::vector<MWTypes*>, but then you have to manage your instances correctly to avoid memory leaks.
class RowSet
{
public:
// addElement assumes responsibility for the memory allocated for each 'elem'
void addElement(MWTypes* elem);
MWTypes* getElement();
std::vector<MWTypes*> getVector() { return m_row; }
// Destructor calls delete on every pointer in m_row
~RowSet();
private:
std::vector<MWTypes*> m_row;
};
Then you need to fix your code which calls addElement() to create new instances, and to get the long back again:
rowSet.getElement()->get();
You're problem lies with this function void addElememnt(MWTypes elem);. It should be either void addElememnt(MWTypes* elem); or void addElememnt(MWTypes& elem);. This is because by having an argument to be passed by-value, it loses it's polymorphism. The passing by-value calls the copy constructor of the base class and ONLY copies the contents of the base class (and the vtable) ignoring the rest from the derived class.
Also, if you need to store values of a certain base-class type, you need to consider using a list of pointers of the base-class type.
The problem lies here:
class RowSet
{
public:
void addElememnt(MWTypes elem);
You are taking elem by value, not by pointer or by reference, so the TypeLong subobject is sliced away, here: (reference: What Is The Slicing Problem in C++?)
TypeLong longObj(_long);
MWTypes *ptr = &longObj;
_long++;
rowSet.addElememnt(*ptr);
You need to change addElement to take a reference or a pointer.
Your vector, getElement, and addElememnt parts all invoke object slicing since they store the base object by value. You need to work with pointers or references in order to use runtime polymorphism.
In this case either a boost::ptr_vector or a vector of shared_ptr is probably what you want.
I'm learning C++ and I'm still confused about this. What are the implications of return a value as constant, reference and constant reference in C++ ? For example:
const int exampleOne();
int& exampleTwo();
const int& exampleThree();
Here's the lowdown on all your cases:
• Return by reference: The function call can be used as the left hand side of an assignment. e.g. using operator overloading, if you have operator[] overloaded, you can say something like
a[i] = 7;
(when returning by reference you need to ensure that the object you return is available after the return: you should not return a reference to a local or a temporary)
• Return as constant value: Prevents the function from being used on the left side of an assignment expression. Consider the overloaded operator+. One could write something like:
a + b = c; // This isn't right
Having the return type of operator+ as "const SomeType" allows the return by value and at the same time prevents the expression from being used on the left side of an assignment.
Return as constant value also allows one to prevent typos like these:
if (someFunction() = 2)
when you meant
if (someFunction() == 2)
If someFunction() is declared as
const int someFunction()
then the if() typo above would be caught by the compiler.
• Return as constant reference: This function call cannot appear on the left hand side of an assignment, and you want to avoid making a copy (returning by value). E.g. let's say we have a class Student and we'd like to provide an accessor id() to get the ID of the student:
class Student
{
std::string id_;
public:
const std::string& id() const;
};
const std::string& Student::id()
{
return id_;
}
Consider the id() accessor. This should be declared const to guarantee that the id() member function will not modify the state of the object. Now, consider the return type. If the return type were string& then one could write something like:
Student s;
s.id() = "newId";
which isn't what we want.
We could have returned by value, but in this case returning by reference is more efficient. Making the return type a const string& additionally prevents the id from being modified.
The basic thing to understand is that returning by value will create a new copy of your object. Returning by reference will return a reference to an existing object. NOTE: Just like pointers, you CAN have dangling references. So, don't create an object in a function and return a reference to the object -- it will be destroyed when the function returns, and it will return a dangling reference.
Return by value:
When you have POD (Plain Old Data)
When you want to return a copy of an object
Return by reference:
When you have a performance reason to avoid a copy of the object you are returning, and you understand the lifetime of the object
When you must return a particular instance of an object, and you understand the lifetime of the object
Const / Constant references help you enforce the contracts of your code, and help your users' compilers find usage errors. They do not affect performance.
Returning a constant value isn't a very common idiom, since you're returning a new thing anyway that only the caller can have, so it's not common to have a case where they can't modify it. In your example, you don't know what they're going to do with it, so why should you stop them from modifying it?
Note that in C++ if you don't say that something is a reference or pointer, it's a value so you'll create a new copy of it rather than modifying the original object. This might not be totally obvious if you're coming from other languages that use references by default.
Returning a reference or const reference means that it's actually another object elsewhere, so any modifications to it will affect that other object. A common idiom there might be exposing a private member of a class.
const means that whatever it is can't be modified, so if you return a const reference you can't call any non-const methods on it or modify any data members.
Return by reference.
You can return a reference to some value, such as a class member. That way, you don't create copies. However, you shouldn't return references to values in a stack, as that results in undefined behaviour.
#include <iostream>
using namespace std;
class A{
private: int a;
public:
A(int num):a(num){}
//a to the power of 4.
int& operate(){
this->a*=this->a;
this->a*=this->a;
return this->a;
}
//return constant copy of a.
const int constA(){return this->a;}
//return copy of a.
int getA(){return this->a;}
};
int main(){
A obj(3);
cout <<"a "<<obj.getA()<<endl;
int& b=obj.operate(); //obj.operate() returns a reference!
cout<<"a^4 "<<obj.getA()<<endl;
b++;
cout<<"modified by b: "<<obj.getA()<<endl;
return 0;
}
b and obj.a "point" to the same value, so modifying b modifies the value of obj.a.
$./a.out
a 3
a^4 81
modified by b: 82
Return a const value.
On the other hand, returning a const value indicates that said value cannot be modified. It should be remarked that the returned value is a copy.:
For example,
constA()++;
would result in a compilation error, since the copy returned by constA() is constant. But this is just a copy, it doesn't imply that A::a is constant.
Return a const reference.
This is similiar to returning a const value, except that no copy is return, but a reference to the actual member. However, it cant be modified.
const int& refA(){return this->a;}
const int& b = obj.refA();
b++;
will result in a compilation error.
const int exampleOne();
Returns a const copy of some int. That is, you create a new int which may not be modified. This isn't really useful in most cases because you're creating a copy anyway, so you typically don't care if it gets modified. So why not just return a regular int?
It may make a difference for more complex types, where modifying them may have undesirable sideeffects though. (Conceptually, let's say a function returns an object representing a file handle. If that handle is const, the file is read-only, otherwise it can be modified. Then in some cases it makes sense for a function to return a const value. But in general, returning a const value is uncommon.
int& exampleTwo();
This one returns a reference to an int. This does not affect the lifetime of that value though, so this can lead to undefined behavior in a case such as this:
int& exampleTwo() {
int x = 42;
return x;
}
we're returning a reference to a value that no longer exists. The compiler may warn you about this, but it'll probably compile anyway. But it's meaningless and will cause funky crashes sooner or later. This is used often in other cases though. If the function had been a class member, it could return a reference to a member variable, whose lifetime would last until the object goes out of scope, which means function return value is still valid when the function returns.
const int& exampleThree();
Is mostly the same as above, returning a reference to some value without taking ownership of it or affecting its lifetime. The main difference is that now you're returning a reference to a const (immutable) object. Unlike the first case, this is more often useful, since we're no longer dealing with a copy that no one else knows about, and so modifications may be visible to other parts of the code. (you may have an object that's non-const where it's defined, and a function that allows other parts of the code to get access to it as const, by returning a const reference to it.
Your first case:
const int exampleOne();
With simple types like int, this is almost never what you want, because the const is pointless. Return by value implies a copy, and you can assign to a non-const object freely:
int a = exampleOne(); // perfectly valid.
When I see this, it's usually because whoever wrote the code was trying to be const-correct, which is laudable, but didn't quite understand the implications of what they were writing. However, there are cases with overloaded operators and custom types where it can make a difference.
Some compilers (newer GCCs, Metrowerks, etc) warn on behavior like this with simple types, so it should be avoided.
I think that your question is actually two questions:
What are the implications of returning a const.
What are the implications of returning a reference.
To give you a better answer, I will explain a little more about both concepts.
Regarding the const keyword
The const keyword means that the object cannot be modified through that variable, for instance:
MyObject *o1 = new MyObject;
const MyObject *o2 = o1;
o1->set(...); // Will work and will change the instance variables.
o2->set(...); // Won't compile.
Now, the const keyword can be used in three different contexts:
Assuring the caller of a method that you won't modify the object
For example:
void func(const MyObject &o);
void func(const MyObject *o);
In both cases, any modification made to the object will remain outside the function scope, that's why using the keyword const I assure the caller that I won't be modifying it's instance variables.
Assuring the compiler that a specific method do not mutate the object
If you have a class and some methods that "gets" or "obtains" information from the instance variables without modifying them, then I should be able to use them even if the const keyword is used. For example:
class MyObject
{
...
public:
void setValue(int);
int getValue() const; // The const at the end is the key
};
void funct(const MyObject &o)
{
int val = o.getValue(); // Will compile.
a.setValue(val); // Won't compile.
}
Finally, (your case) returning a const value
This means that the returned object cannot be modified or mutated directly. For example:
const MyObject func();
void func2()
{
int val = func()->getValue(); // Will compile.
func()->setValue(val); // Won't compile.
MyObject o1 = func(); // Won't compile.
MyObject o2 = const_cast<MyObject>(func()); // Will compile.
}
More information about the const keyword: C++ Faq Lite - Const Correctness
Regarding references
Returning or receiving a reference means that the object will not be duplicated. This means that any change made to the value itself will be reflected outside the function scope. For example:
void swap(int &x, int &y)
{
int z = x;
x = y;
y = z;
}
int a = 2; b = 3;
swap(a, b); // a IS THE SAME AS x inside the swap function
So, returning a reference value means that the value can be changed, for instance:
class Foo
{
public:
...
int &val() { return m_val; }
private:
int m_val;
};
Foo f;
f.val() = 4; // Will change m_val.
More information about references: C++ Faq Lite - Reference and value semantics
Now, answering your questions
const int exampleOne();
Means the object returned cannot change through the variable. It's more useful when returning objects.
int& exampleTwo();
Means the object returned is the same as the one inside the function and any change made to that object will be reflected inside the function.
const int& exampleThree();
Means the object returned is the same as the one inside the function and cannot be modified through that variable.
Never thought, that we can return a const value by reference and I don't see the value in doing so..
But, it makes sense if you try to pass a value to a function like this
void func(const int& a);
This has the advantage of telling the compiler to not make a copy of the variable a in memory (which is done when you pass an argument by value and not by reference). The const is here in order to avoid the variable a to be modified.
As far as I can tell, there's no reason I shouldn't be allowed to pass a reference to a pointer in C++. However, my attempts to do so are failing, and I have no idea why.
This is what I'm doing:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
And I'm getting this error:
cannot convert parameter 1 from 'std::string *' to 'std::string *&'
Your function expects a reference to an actual string pointer in the calling scope, not an anonymous string pointer. Thus:
string s;
string* _s = &s;
myfunc(_s);
should compile just fine.
However, this is only useful if you intend to modify the pointer you pass to the function. If you intend to modify the string itself you should use a reference to the string as Sake suggested. With that in mind it should be more obvious why the compiler complains about you original code. In your code the pointer is created 'on the fly', modifying that pointer would have no consequence and that is not what is intended. The idea of a reference (vs. a pointer) is that a reference always points to an actual object.
The problem is that you're trying to bind a temporary to the reference, which C++ doesn't allow unless the reference is const.
So you can do one of either the following:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
void myfunc2(string* const& val)
{
// Do stuff to the string pointer
}
int main()
// sometime later
{
// ...
string s;
string* ps = &s;
myfunc( ps); // OK because ps is not a temporary
myfunc2( &s); // OK because the parameter is a const&
// ...
return 0;
}
Change it to:
std::string s;
std::string* pS = &s;
myfunc(pS);
EDIT:
This is called ref-to-pointer and you cannot pass temporary address as a reference to function. ( unless it is const reference).
Though, I have shown std::string* pS = &s; (pointer to a local variable), its typical usage would be :
when you want the callee to change the pointer itself, not the object to which it points. For example, a function that allocates memory and assigns the address of the memory block it allocated to its argument must take a reference to a pointer, or a pointer to pointer:
void myfunc(string*& val)
{
//val is valid even after function call
val = new std::string("Test");
}
&s produces temporary pointer to string and you can't make reference to temporary object.
Try:
void myfunc(string& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(s);
// ...
}
or
void myfunc(string* val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
EDIT: I experimented some, and discovered thing are a bit subtler than I thought. Here's what I now think is an accurate answer.
&s is not an lvalue so you cannot create a reference to it unless the type of the reference is reference to const. So for example, you cannot do
string * &r = &s;
but you can do
string * const &r = &s;
If you put a similar declaration in the function header, it will work.
void myfunc(string * const &a) { ... }
There is another issue, namely, temporaries. The rule is that you can get a reference to a temporary only if it is const. So in this case one might argue that &s is a temporary, and so must be declared const in the function prototype. From a practical point of view it makes no difference in this case. (It's either an rvalue or a temporary. Either way, the same rule applies.) However, strictly speaking, I think it is not a temporary but an rvalue. I wonder if there is a way to distinguish between the two. (Perhaps it is simply defined that all temporaries are rvalues, and all non-lvalues are temporaries. I'm not an expert on the standard.)
That being said, your problem is probably at a higher level. Why do you want a reference to the address of s? If you want a reference to a pointer to s, you need to define a pointer as in
string *p = &s;
myfunc(p);
If you want a reference to s or a pointer to s, do the straightforward thing.
Welcome to C++11 and rvalue references:
#include <cassert>
#include <string>
using std::string;
void myfunc(string*&& val)
{
assert(&val);
assert(val);
assert(val->c_str());
// Do stuff to the string pointer
}
// sometime later
int main () {
// ...
string s;
myfunc(&s);
// ...
}
Now you have access to the value of the pointer (referred to by val), which is the address of the string.
You can modify the pointer, and no one will care. That is one aspect of what an rvalue is in the first place.
Be careful: The value of the pointer is only valid until myfunc() returns. At last, its a temporary.
I have just made use of a reference to a pointer to make all the pointers in a deleted binary tree except the root safe. To make the pointer safe we just have to set it to 0. I could not make the function that deletes the tree (keeping only the root) to accept a ref to a pointer since I am using the root (this pointer) as the first input to traverse left and right.
void BinTree::safe_tree(BinTree * &vertex ) {
if ( vertex!=0 ) { // base case
safe_tree(vertex->left); // left subtree.
safe_tree(vertex->right); // right subtree.
// delete vertex; // using this delete causes an error, since they were deleted on the fly using inorder_LVR. If inorder_LVR does not perform delete to the nodes, then, use delete vertex;
vertex=0; // making a safe pointer
}
} // end in
Bottom line, a reference to a pointer is invalid when the formal parameter is the (this) pointer.
I know that it's posible to pass references of pointers, I did it last week, but I can't remember what the syntax was, as your code looks correct to my brain right now. However another option is to use pointers of pointers:
Myfunc(String** s)
myfunc("string*& val") this itself doesn't make any sense. "string*& val" implies "string val",* and & cancels each other. Finally one can not pas string variable to a function("string val"). Only basic data types can be passed to a function, for other data types need to pass as pointer or reference.
You can have either string& val or string* val to a function.