Is there a way to change what THIS point to?
class foo{...}
foo* fooinstance = new foo();
foo* otherfooinstance = new foo();
void
foo::bar(){
this = otherfooinstance;
}
fooinstance->bar();
for those of you who are wondering in what case I would change the this pointer here is case. I had to do a tree recursion where I had to remove intermediate nodes.. for this example lets assume the intermediate nodes of removal have the title d. and these intermediate nodes only have one child. So in lisp notation if we have a tree like
(g (d (i 4)) (i 5))
the function removeIntermediates(tree) would in effect cause the above to become
(g (i 4) (i 5))
and the pseudo code for this IF the this pointer was reassignable would look like the following..
DTREE::removeIntermediates(){
this = child(0); removeIntermediates();
}
TREE::removeIntermediates(){
for each child { child->removeIntermediates();
}
I wanted to do this without knowing what the child node was therefore making code factorable into different functions for each node type and having a general function for other types.
Sadly, I just ended up doing something like this..
TREE::removeIntermediates(){
for each child { if(child->name == "d") {
setchild(child->child(0));
child->removeIntermediates();
}
else { child->removeIntermediates();}
}
No, this is not modifiable.
Conceptually that doesn't make sense, what are you trying to accomplish?
C++ standard forbids assignment to this in "9.3.2 The this pointer" by stating that "keyword this is a non-lvalue expression". Although, some compilers still allow assignment to this by using a certain compile-time switch, because at some point in early drafts C++ standard actually allowed assignment to "this".
Anyway, it is quite hard to imagine a case where you would actually want to do that and it is very likely that there is a clean and beautiful way to do it.
No, you should never, ever, set this.
If you need to point to different objects then define your own variable.
No. This is an rvalue, not an lvalue. The easiest way to think
of it is that it invokes compiler magic to access the object on
which the function was called. You can't modify it any more
than you could modify the constant 3.
Historically, in very early versions of C++, you could modify
it, but only in the constructor, and only as the first thing in
the constructor: the functionality offered by this has been
subsumed by user defined operator new. This was 20-15 years
ago, however.
What are you trying to do? If you just want to access two
different objects from the same member function, that's no
problem: otherfooinstance-> should work, and will give you
access to the private members as well.
The member method void foo::bar() { this = otherfooinstance; } will be compile like this:
void foo__bar(foo * const this) { this = otherfooinstance; }
this is a const pointer to calling foo instance, so you can't change it.
And change this is not a good idea.
The "this" pointer doesn't really exist. That is, it's not stored somewhere with the object. Rather, when a method is called on an object the compiler passes the address of the object as an extra argument. So "this" only ever really appears on the stack while a method is executing.
So even if you did assign to "this" as in your example, your redirection to otherfooinstance would last only for the duration of the current bar() invocation.
Related
I have a library defining method() that returns type V* and can return nullptr. What's the best way to wrap that method to turn the value into a std::optional<V>?
The naive way would be something like:
std::optional<V> maybe_value;
V* value = method();
if (value != nullptr) {
maybe_value = *value; // assuming the type is even copyable
}
But I was hoping there'd already be some STL function I could use to do this as a one-liner wrapper around method().
Your way looks basically fine to me, and is roughly what I'd do. You don't want a one-liner here as it would not be very clear. Ultimately you can create a function for it if you like.
One concern: be very careful with ownership semantics here. Who owns *value? Can it be copied? Is that meaningful? Can you move it instead? Who frees the original object?
Always ask these questions when passed a pointer, even if it appeared that the pointer was only chosen in order to add nullability.
To be quite honest, although std::optional is preferable in new code (or code you're refactoring), I'm not convinced that wrapping a function like this is worth the potential confusion, not to mention the cost of a copy (if, indeed, that is necessary).
There is no such function. Assignment of any value makes the optional containing a value. But you can provide your own
template <typename T>
std::optional<T*> optional_ptr(T* ptr) {
return ptr ? std::optional<T*>(ptr) : std::optional<T*>();
}
Is it possible to force C++ to construct an object in the scope of a calling function? What I mean is to explicitly do what an return value optimization (RVO) does.
I have some container classes which are in a chain of derivation. Since the classes are constructed with stack data, they can't be returned, so I disabled the copy constructor and assignment operators. For each class, I am providing an iterator. The constructor of each iterator has only one argument: a pointer to the container class. To get the iterator, I want to use this function:
BindPackIterator BindPack.begin(void)
{
return BindPackIterator(this);
}
in this context:
for (auto i=bindpack.begin(); !i.end(); ++i) { i.run(); }
The compiler issues errors, complaining about not being able to copy the BindPackIterator object. Remember, I disabled them.
What I want to happen is for the BindPackIterator to be instantiated in the calling function's scope to avoid either a copy or move operation.
In this particular case, I know I can do a workaround, changing the begin function to return a BindPack pointer,
for(BindPackIterator i=bindpack.begin(); !i.end(); ++i) { i.run(); }
and I've experimented a bit, without success, with decltype and this construction:
auto BindPack::begin(void) -> BindPackIterator
{
return BindPackIterator(this);
}
This is just the example with which I'm currently frustrated. There have been other projects where the obvious solution is for the function to instantiate an object in the calling function's scope. The move constructor (foo&&) helps in some cases, but for objects with many data members, even that can be inefficient. Is there a design pattern that allows object construction/instantiation in the caller's scope?
Putting n.m.'s comment into code, write a constructor for BindPackIterator that takes a BindPack and initializes the iterator in the "begin" state. e.g:
BindPackIterator(BindPack* pack) : pack(pack), pos(0){ }
That you can use in your for loop:
BindPack pack;
for(BindPackIterator i(&pack); !i.end(); ++i){
i.run();
}
Live demo
Is it fair to say that the answer is "No," it is not possible to construct a returned object in the calling function's scope? Or in other words, you can't explicitly tell the compiler to use RVO.
To be sure, it is a dangerous possibility: stack memory used to construct the object while available in the called function will not be valid in the calling function, even though the values might remain untouched in the abandoned stack frame. This would result in unpredictable behavior.
Upon further consideration, while summing up at the end of this response, I realized that the compiler may not be able to accurately predict the necessary stack size for objects created in the calling function and initialized in a called function, and it would not be possible to dynamically expand the stack frame if the execution had passed to another function. These considerations make my whole idea impossible.
That said, I want to address the workarounds that solve my iterator example.
I had to abandon the idea of using auto like this:
for (auto i=bindpack.begin(); !i.end(); ++i)
Having abandoned auto, and realizing that it's more sensible to explicitly name the variable anyway (if the iterator is different enough to require a new class, it's better to name it to avoid confusion) , I am using this constructor:
BindPackIterator(BindPack &ref) : m_ref_pack(ref), m_index(0) { }
in order to be able to write:
for (BindPackIterator i=bindpack; !i.end(); ++i)
preferring to initialize with an assignment. I used to do this when I was last heavily using C++ in the late 1990's, but it's not been working for me recently. The compiler would ask for a copy operator I didn't want to define for reasons stated above. Now I think that problem was due to my collection of constructors and assignment operators I define to pass the -Weffc++ test. Using simplified classes for this example allowed it to work.
Another workaround for an object more complicated than an iterator might be to use a tuple for the constructor argument for objects that need multiple variables to initialize. There could be a casting operator that returns the necessary tuple from the class that initializes the object.
The constructor could look like:
FancyObject(BigHairyTuple val) : m_data1(get<0>(val)), m_data2(get<1>(val), etc
and the contributing object would define this:
class Foo
{
...
operator BigHairyTuple(void) {
return BigHairyTuple(val1, val2, ...);
}
};
to allow:
FancyObject fo = foo;
I haven't tested this specific example, but I'm working with something similar and it seems likely to work, with some possible minor refinements.
I need a once-and-for-all clarification on passing by value/pointer/reference.
If I have a variable such as
int SomeInt = 10;
And I want to pass it to a function like
void DoSomething(int Integer)
{
Integer = 1;
}
In my current scenario when passing SomeInt to DoSomething() I want SomeInt's value to be updated based on whatever we do to it inside of DoSomething() as well as be most efficient on memory and performance so I'm not copying the variable around?. That being said which of the following prototypes would accomplish this task?
void DoSomething(int* Integer);
void DoSomething(int& Integer);
How would I actually pass the variable into the function? What is the difference between the previous two prototypes?
Finally if using a function within a class
class SomeClass
{
int MyInteger;
public:
void ChangeValue(int& NewValue)
{
MyInteger = NewValue;
}
};
If I pass an integer into ChangeValue, when the integer I passed in get's deleted will that mean when I try to use MyInteger from within the class it will no longer be useable?
Thank you all for your time, I know this is kind of a basic question but the explanations I keep running into confuse me further.
Functionally, all three of these work:
pass an int and change the return type to int so you can return the new value, usage: x = f(x);
when you plan to set the value without needing to read the initial value, it's much better to use a function like int DoSomething(); so the caller can just say int x = f(); without having to create x on an earlier line and wondering/worrying whether it needs to be initialised to anything before the call.
pass an int& and set it inside the function, usage: int x; x = ? /* if an input */; f(x);
pass an int* and set the pointed-to int inside the function, usage: int x; x = ?; f(&x);
most efficient on memory and performance so I'm not copying the variable around
Given the C++ Standard doesn't dictate how references should be implemented by the compiler, it's a bit dubious trying to reason about their characteristics - if you care compile your code to assembly or machine code and see how it works out on your particular compiler (for specific compiler commandline options etc.). If you need a rule of thumb, assume that references have identical performance characteristics to pointers unless profiling or generated-code inspection suggests otherwise.
For an int you can expect the first version above to be no slower than the pointer version, and possibly be faster, because the int parameter can be passed and returned in a register without ever needing a memory address.
If/when/where the by-pointer version is inlined there's more chance that the potentially slow "needing a memory address so we can pass a pointer" / "having to dereference a pointer to access/update the value" aspect of the pass-by-pointer version can be optimised out (if you've asked the compiler to try), leaving both versions with identical performance....
Still, if you need to ask a question like this I can't imagine you're writing code where these are the important optimisation choices, so a better aim is to do what gives you the cleanest, most intuitive and robust usage for the client code... now - whether that's x = f(x); (where you might forget the leading x =), or f(x) where you might not realise x could be modified, or f(&x) (where some caller might think they can pass nullptr is a reasonable question in its own right, but separate from your performance concerns. FWIW, the C++ FAQ Lite recommends references over pointers for this kind of situation, but I personally reject its reasoning and conclusions - it all boils down to familiarity with either convention, and how often you need to pass const pointer values, or pointer values where nullptr is a valid sentinel, that could be confused with the you-may-modify-me implication hoped for in your scenario... that depends a lot on your coding style, libraries you use, problem domain etc..
Both of your examples
void DoSomething(int* Integer);
void DoSomething(int& Integer);
will accomplish the task. In the first case - with pointer - you need to call the function with DoSomething(&SomeInt);, in the second case - with reference - simpler as DoSomething(SomeInt);
The recommended way is to use references whenever they are sufficient, and pointers only if they are necessary.
You can use either. Function call for first prototype would be
DoSomething(&SomeInt);
and for second prototype
DoSomething(SomeInt);
As was already said before, you can use both. The advantage of the
void DoSomething(int* Integer)
{
*Integer=0xDEADBEEF;
}
DoSomething(&myvariable);
pattern is that it becomes obvious from the call that myvariable is subject to change.
The advantage of the
void DoSomething(int& Integer)
{
Integer=0xDEADBEEF;
}
DoSomething(myvariable);
pattern is that the code in DoSomething is a bit cleaner, DoSomething has a harder time to mess with memory in bad ways and that you might get better code out of it. Disadvantage is that it isn't immediately obvious from reading the call that myvariable might get changed.
Suppose I have this setup:
struct XView;
struct X
{
...
XView view;
};
Type XView is only used for this one field; it is internal too, so instantiating it from outside, i.e. using it for anything else is prohibited.
So, assuming any object of XView type is an X::view field, is it possible to find address of X from address of XView, staying fully within behavior defined by C++ standard and without type-punning? I.e. is it possible to do something like this:
void XView::some_function ()
{
X& this_x = some_computations_involving (this);
}
I can of course store a pointer, so this would become as trivial as x = *this->parent_x, but would like to do without one if possible.
EDIT: Note that I need an answer without type-punning involved, otherwise I'd rather use that "just store a pointer" solution.
First approach is to make XView the first member of X, then you can do this:
void XView::some_function ()
{
X & this_x = reinterpret_cast<X&>(*this);
}
Second approach is to use offset when XView is not the first member of the X.
Techinically speaking both of these approaches are same if there is no virtuality involved, only that the first approach is a special case (i.e when offset = 0) of the second approach which is the general case.
As for the edit, I think, without casting it is not possible. You have to store the pointer in XView, Or maintaining a map (or some other data structures) of pointers.
The most important thing is whether you really need accessing the parent object from child object and not vice-versa.
I would suggest you using some kind of bi-directional linked list or something like this.
Could your code be refactored to be more object-oriented? (and possibly using the inheritance (and calling the parent by using the super::some_function...)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
What does Class& mean in c++ and how is it different from Class*?
Class& foo;
Class* foo;
The & version represents a reference while the * version represents a pointer. The difference is far too big for a typical SO post. I suggest you start at the C++ FAQ lite
http://www.parashift.com/c++-faq-lite/references.html
I usually don't like to answer posts with a "you should use google" answer. However this is one topic that I highly advise you google. In particular google "c++ pointers vs. references". There is a wealth of information available on this topic and the discussions on those pages will trump anything we'll write here.
The * is a pointer, the & is a reference. The difference between the two is that a pointer is an area of memory that must be dereferenced, eg. by means of the -> operator in order to be "seen" as a class instance. A reference is instead an "alias", just an alternative name for the same class instance. You don't need to use the -> operator with a reference. You use the dot operator.
Personally, I rarely used the references, mostly when I had a value object that I allocated on the stack. The new operator always returns a pointer, which you then have to dereference. Moreover, one of the most problematic issues of the references is that you cannot set them to NULL. In some cases, it is handy to have a function that accepts either an object pointer or NULL. If your function accepts a reference, you cannot pass a NULL (you could use the Null object pattern, however)
A Class * can point at any class object, or none.
A Class & always points to exactly one class object, and can never point to a different one.
Furthermore, I believe Bjarne is a member of the set of people who have asserted "arrays in C are broken beyond repair," a Class * can point at a whole ding-dang array of class objects, lined up one after the other in memory, and there is absolutely no way in C to tell whether a Class * points at one or many.
Another difference is that reference variables must be initialized. You cannot create a reference variable like what is shown in the sample code. That would produce a compiler error.
As stated you should google it, but to avoid misunderstanding:
References are NOT variables
References are NOT similar to pointers (but you can use them in a similar way)
Think of a Reference as a shortcut for the term that is assigned to it.
One additional tip that I would offer is the following:
Use references when you can, pointers when you have to. If the object is guaranteed to exist, you should probably use a reference. If it is not, then you probably have to use a pointer.
One additional advantage is that references remove ambiguity on ownership. As soon as a maintenance programmer sees a pointer, they'll start to wonder if they should delete it.
Check this example out:
// Wrapper class using a reference because the wrapped object always exists
class Wrapper
{
public:
// If the wrapped is guaranteed to exist at creation, do it this way
Wrapper(Wrapped& wrapped):_wrapped(wrapped) { /* empty */ }
// put extra methods here.
int getWrappedValue() const { return _wrapped.getValue(); }
private:
Wrapped& _wrapped; // This object always exists and is valid
};
// Wrapper class written to support a possibly non-existent wrapped object.
class Wrapper
{
public:
Wrapper(Wrapped* wrapped = 0):_wrapped(wrapped) { /* empty */
void setWrappee(WRappee* wrapped) { _wrapped = wrapped; }
int getWrappedValue() const; // Not making inline -- more complex
private:
Wrapped* _wrapped; // Always check pointer before use
};
int Wrapper::getWrappedValue() const
{
if (_wrapped)
{
return _wrapped->getValue();
}
else
{
return -1; // NOTE, this is a contrived example -- not getting into exceptions
}
}
A reference (&) is just the same as a pointer (*), except that the C++ compiler ensures it not to be NULL. However, it can still be a dangling pointer (a pointer variable that has no reference such that it is garbage and invalid for any use).