Smart Pointer behavior using * - c++

I have the following code snippet:
QList<const GLMeshPtr*> meshList;
m_itemsList->getSelectedMeshes(meshList);
for (auto m : meshList)
{
if (GLBodyPtr c = (*m)->getStandard()) {
c->executeMeshFix();
}
}
GLMeshPtr is set as in this typedef:
typedef std::shared_ptr<GLMesh> GLMeshPtr;
The definition of m_itemsList->getSelectedMeshes is:
void QMeshList::getSelectedMeshes(QList<const GLMeshPtr*>& list)
{
for (auto& m : m_meshList) {
if (m->isSelected()) {
list.push_back(m->getGLMesh());
}
}
}
Definition for getGLMesh is:
const GLMeshPtr* getGLMesh() const { return &m_glmesh; } // where m_glmesh is a GLMeshPtr.
My question is very simple, yet, I couldn't find any reference to it. Does the * keyword create a copy of the value in the stack, necessarily, or does it use the value "in place"?
I talk more specifically about this line:
if (GLBodyPtr c = (*m)->getStandard()) {
Am I creating unnecessary copies of GLBodyPtr? I don't want anyone here to share the pointer.

No, the * operator returns a reference, i.e. GLBodyPtr const&. It is const because the pointer is declared to point to a const object. See definition of std::shared_ptr::operator* on cppreference.com.
References are basically like pointers that can't be changed once they're initialized, so it's not a copy of the shared_ptr object.

Related

Using pointer vector to reference vector is illegal?

I have one question.
Is it ok to use pointer vector as reference vector?
Struct Child
{
int n;
void func(int _n)
{
n = _n;
};
}
struct Parent
{
std::vector<Child> vec;
}
void func(Parent* p)
{
std::vector<Child>& ref = p->vec; // is this ok?
int value = 10;
ref[0].func(value); // is this ok?
}
int main()
{
...
...
Parent p;
func(&p);
...
...
return 0;
}
compiler gcc 4.4.7 (under c++11)
I guess, would it be okay if changed the value of the reference?
ref[0].func(value)
Thank you.
std::vector<Child>& ref = p->vec; // is this ok? yes
int value = 10;
ref->func(value); // is this ok? no
ref is not a pointer so you cannot use the member access operator ->
ref is a vector, so you need to pick which Child you want to use.
ref[ child_index ].func(value);
reference is nothing else but another name of an object. So these are all the same:
std::vector<Child>& ref = p->vec;
std::vector<Child>& vecAlias = ref;
int value = 10;
ref[0].func(value);
vecAlias[0].func(value);
p->vec[0].func(value);
You can't change a value of a reference. Uninitialized referenced don't exist. Once it's initialized there is no way of changing it.
Pointers on the other hand have similar purpose: they allow access to the same data from different places. You can always change what a pointer points to. But pointers are also more error-prone as then can be uninitialized or null-initialized. So try to stick to references if you don't need this flexibility.

Is it possible to return a reference via an argument passed by reference?

I want to return a boolean or success/failure enum from the function and modify an argument by reference. However, I want to construct a reference in the calling function instead of copying the value.
I have some container (say 'example_q' of type std::queue). queue.front() will return a reference to the value stored in the queue. I can make a copy of that reference (example A) or I can take a reference of that reference (example B), allowing the value to stay in the queue but be utilized outside of it.
A)
int a = example_q.front();
B)
int& b = example_q.front();
Using this difference I could also return the queued value:
A)
int get_front()
{
int a = example_q.front();
return a;
}
B)
int& get_front()
{
return example_q.front();
}
Using option 'B' I can avoid unnecessary copies without moving the data out of the queue via std::move() semantics.
My question is, can I do 'B' via an argument passed by reference? Would I need to use std::move()/rvalues/&& somehow?
void get_front(int& int_ref)
{
// somehow don't copy the value into referenced int_ref, but construct
// a reference in the caller based on an input argument?
int_ref = example_q.front();
}
The problem this would solve is making API match other functions that modify reference arguments but return a success/failure value, ie:
if(q.get_front(referrence_magic_here))
{
...
}
I could reverse the order to get the desired result, IE:
int& get_front(bool& success)
{
...
}
But I'd rather keep the pattern of my API as well as being able to do it via a single line in the if() statement if possible.
Perhaps something like:
bool get_front(int&& int_rvalue)
{
...
int_rvalue = example_q.front();
...
return true_or_false;
}
void calling_func()
{
...
if(get_front(int& magical_ref))
{
... //use magical_ref here?
}
...
}
No, you can't do that.
Other than in its initialiser, a reference behaves like the thing it refers to. By passing it as a function argument, you "hide" the initialiser from the part that wants to do the assignment. So, the function has no access to the referencey behaviour of the thing.
You will have to use pointers if you want to do that:
void get_front(int*& int_ptr)
{
int_ptr = &example_q.front();
}
int* ptr = nullptr;
get_front(ptr);
// optional:
int& ref = *ptr;
(Ew!)
Option B was fine.
This code is invalid C++:
if(get_front(int& magical_ref))
You cannot declare a new variable as you're passing it to a function. And because a reference variable must be declared and initialized at the same time, it wouldn't be possible to have a reference be initialized by passing it to a function.
You could however, do this:
if(int &magical_ref = get_front()) {
But note that you'd be checking whether magical_ref is 0 or not, which is different from the condition you have in your example.
If your logic is as simple as comparing the int, you could do:
if (int& magical_ref = get_front(); magical_ref == 42)
You can return a std::tuple<int&, /* status condition */> and check the status. For example:
std::tuple<int&, bool> get_front() {
static int example = 0;
return {example, false};
}
...
// C++17's structured bindings + if statement with initializer
if (auto [ref, success] = get_front(); success) {
ref = 42;
}
Demo

Replacing a non-copyable, non-movable object

Consider the following code:
// A non-copyable, non-movable aggregate
struct Strange
{
const int & i;
char & c;
};
class Container
{
private:
int my_i;
char my_c;
Strange thing;
public:
// Valid, because both `my_i´ and `my_c´ are non-const
// objects to which both references can be bound.
explicit
Container
( )
noexcept
: thing{ my_i , my_c }
{ }
// How could this be implemented?
auto &
operator=
( const Container & that )
noexcept
{
this->my_i = that->my_i;
this->my_c = that->my_c;
// What to do with `thing´?
return *this;
}
};
Possible solutions
Dynamically allocate the Strange object
class Container
{
private:
int my_i;
char my_c;
Strange * thing;
public:
// Note that it isn't exception safe.
explicit
Container
( )
: thing(new Strange{ my_i , my_c })
{ }
auto &
operator=
( const Container & that )
noexcept
{
this->my_i = that->my_i;
this->my_c = that->my_c;
delete this->thing;
this->thing = new Strange { this->my_i , this->my_c };
return *this;
}
};
Concerns:
Not efficient.
Not safe: allocation may fail and throw.
Dangerous: great care has to be taken not to leak memory.
Using a smart pointer (i.e. std::unique_ptr) would solve only the last point, aside from making the code more readable.
Use placement new
class Container
{
private:
int my_i;
char my_c;
Strange thing;
public:
explicit
Container
( )
noexcept
: thing{ my_i , my_c }
{ }
auto &
operator=
( const Container & that )
noexcept
{
this->my_i = that.my_i;
this->my_c = that.my_c;
// Placement new is exception safe, and so is
// construction of `Strange´.
this->thing.~Strange();
new(&this->thing) Strange { this->my_i , this->my_c };
return *this;
}
};
Concerns:
Will Strange's destructor free the memory taken by thing?
I think that, just as constructors, destructors are not responsible for memory management. Moreover, my code seems to work fine. However, I would like clarification on this.
What about memory alignment?
My guess is that, since it replaces an existing object of the same type, memory would already be aligned. Is this correct?
Would Container's destructor take care of destructing thing?
Questions
Aside from corroborating and/or refuting the concerns I explained above, I would like to know if there are other alternatives. If so, please, give an example implementation.
This question arose when working on a class that ought to offer an interface similar to that of std::unordered_map. Instead of reimplementing it, my class encapsulates such container, and just acts as a proxy for most methods: its iterators envelop those provided by the map, and its pair is an aggregate structure with appropiately named members (which are references to the actual data), represented in the examples provided as Strange. Since iterators are required to return references and pointers to the actual data, my custom iterators contain a pair. The problem was modifying it (when incrementing or assigning the iterator). I acknowledge that this probably isn't a good idea, and that those references will impact performance, but am anyway interested in the matter.
Edit
I have just realized that, instead of returning references and pointers to a member custom pair pointing to the actual data (that of the encapsulated map) from my custom iterator, I could return in-place constructed custom pairs (i.e. Strange objects). Often, we do not see that we are in a cave, and instead of exiting it, continue forward :). Excuse me for the noise, I'll mark the question as "Closed".
(If we're talking about moving objects and using the auto keyword, you should add the c++11 tag to your question).
I'm not sure I really understand your question; the example you gave doesn't seem well thought to me; it would be much better to use pointers in Strange.
For example, this compiles and works absolutely fine, and is functionally equivalent to what you want to do I think.
struct Strange
{
Strange()
: i(nullptr), c(nullptr) {}
Strange( const int *_i, const char *_c )
: i(_i), c(_c) {}
const int *i;
const char *c;
};
class Container
{
int my_i;
char my_c;
Strange thing;
public:
Container()
: thing(&my_i,&my_c)
{ }
Container( int i, char c )
: my_i(i), my_c(c), thing(&my_i,&my_c)
{ }
Container( int i, char c, const Strange& s )
: my_i(i), my_c(c), thing(s) // use default copy-constructor
{ }
Container &
operator=
( const Container & that )
{
my_i = that.my_i;
my_c = that.my_c;
thing = that.thing;
return *this;
}
};
int main()
{
Container a(12,24);
Container b(25,42);
b = a;
}
Note that referencing memory within objects is generally dangerous.
For example, using memcpy on this would be a catastrophy.
(Compiled with clang and g++)

recursive application of operator->

It is said that the arrow operator is applied recursively. But when I try to execute the following code, it prints gibberish when it is supposed to print 4.
class dummy
{
public:
int *p;
int operator->()
{
return 4;
}
};
class screen
{
public:
dummy *p;
screen(dummy *pp): p(pp){}
dummy* operator->()
{
return p;
}
};
int main()
{
dummy *d = new dummy;
screen s(d);
cout<<s->p;
delete d;
}
What Stanley meant by “recursive” is just that the operator is applied to every returned object until the returned type is a pointer.
Which happens here on the first try: screen::operator -> returns a pointer. Thus this is the last call to an operator -> that the compiler attempts. It then resolves the right-hand sice of the operator (p) by looking up a member in the returned pointee type (dummy) with that name.
Essentially, whenever the compiler finds the syntax aᵢ->b in code, it essentially applies the following algorithm:
Is aᵢ of pointer type? If so, resolve member b of *aᵢ and call (*aᵢ).b.
Else, try to resolve aᵢ::operator ->
On success, set aᵢ₊₁ = aᵢ::operator ->(). Goto 1.
On failure, emit a compile error.
I’m hard-pressed to come up with a short, meaningful example where a chain of operator -> invocations even makes sense. Probably the only real use is when you write a smart pointer class.
However, the following toy example at least compiles and yields a number. But I wouldn’t advise actually writing such code. It breaks encapsulation and makes kittens cry.
#include <iostream>
struct size {
int width;
int height;
size() : width(640), height(480) { }
};
struct metrics {
size s;
size const* operator ->() const {
return &s;
}
};
struct screen {
metrics m;
metrics operator ->() const {
return m;
}
};
int main() {
screen s;
std::cout << s->width << "\n";
}
C++ Primer (5th edition) formulates it as follows on page 570:
The arrow operator never loses its fundamental meaning of member access. When we overload arrow, we change the object from which arrow fetches the specified member. We cannot change the fact that arrow fetches a member.
The deal is once screen::operator->() returns a pointer (dummy*) the recursion stops because built-in (default) -> in used on that pointer. If you want recursion you should return dummy or dummy& from screen::operator->()

Returning a "NULL reference" in C++?

In dynamically typed languages like JavaScript or PHP, I often do functions such as:
function getSomething(name) {
if (content_[name]) return content_[name];
return null; // doesn't exist
}
I return an object if it exists or null if not.
What would be the equivalent in C++ using references? Is there any recommended pattern in general? I saw some frameworks having an isNull() method for this purpose:
SomeResource SomeClass::getSomething(std::string name) {
if (content_.find(name) != content_.end()) return content_[name];
SomeResource output; // Create a "null" resource
return output;
}
Then the caller would check the resource that way:
SomeResource r = obj.getSomething("something");
if (!r.isNull()) {
// OK
} else {
// NOT OK
}
However, having to implement this kind of magic method for each class seems heavy. Also it doesn't seem obvious when the internal state of the object should be set from "null" to "not null".
Is there any alternative to this pattern? I already know it can be done using pointers, but I am wondering how/if it can be done with references. Or should I give up on returning "null" objects in C++ and use some C++-specific pattern? Any suggestion on the proper way to do that would be appreciated.
You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.
With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):
SomeResource* SomeClass::getSomething(std::string name) {
std::map<std::string, SomeResource>::iterator it = content_.find(name);
if (it != content_.end())
return &(*it);
return NULL;
}
Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):
std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) {
std::map<std::string, SomeResource>::iterator it = content_.find(name);
if (it != content_.end())
return std::make_pair(*it, true);
return std::make_pair(SomeResource(), false);
}
Using boost::optional:
boost::optional<SomeResource> SomeClass::getSomething(std::string name) {
std::map<std::string, SomeResource>::iterator it = content_.find(name);
if (it != content_.end())
return *it;
return boost::optional<SomeResource>();
}
If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.
I also modified your example so you're not searching the map twice (by reusing the iterator).
Why "besides using pointers"? Using pointers is the way you do it in C++. Unless you define some "optional" type which has something like the isNull() function you mentioned. (or use an existing one, like boost::optional)
References are designed, and guaranteed, to never be null. Asking "so how do I make them null" is nonsensical. You use pointers when you need a "nullable reference".
One nice and relatively non-intrusive approach, which avoids the problem if implementing special methods for all types, is that used with boost.optional. It is essentially a template wrapper which allows you to check whether the value held is "valid" or not.
BTW I think this is well explained in the docs, but beware of boost::optional of bool, this is a construction which is hard to interpret.
Edit: The question asks about "NULL reference", but the code snippet has a function that returns by value. If that function indeed returned a reference:
const someResource& getSomething(const std::string& name) const ; // and possibly non-const version
then the function would only make sense if the someResource being referred to had a lifetime at least as long as that of the object returning the reference (otherwise you woul dhave a dangling reference). In this case, it seems perfectly fine to return a pointer:
const someResource* getSomething(const std::string& name) const; // and possibly non-const version
but you have to make it absolutely clear that the caller does not take ownership of the pointer and should not attempt to delete it.
I can think of a few ways to handle this:
As others suggested, use boost::optional
Make the object have a state that indicates it is not valid (Yuk!)
Use pointer instead of reference
Have a special instance of the class that is the null object
Throw an exception to indicate failure (not always applicable)
unlike Java and C# in C++ reference object can't be null.
so I would advice 2 methods I use in this case.
1 - instead of reference use a type which have a null such as std::shared_ptr
2 - get the reference as a out-parameter and return Boolean for success.
bool SomeClass::getSomething(std::string name, SomeResource& outParam) {
if (content_.find(name) != content_.end())
{
outParam = content_[name];
return true;
}
return false;
}
This code below demonstrates how to return "invalid" references; it is just a different way of using pointers (the conventional method).
Not recommended that you use this in code that will be used by others, since the expectation is that functions that return references always return valid references.
#include <iostream>
#include <cstddef>
#define Nothing(Type) *(Type*)nullptr
//#define Nothing(Type) *(Type*)0
struct A { int i; };
struct B
{
A a[5];
B() { for (int i=0;i<5;i++) a[i].i=i+1; }
A& GetA(int n)
{
if ((n>=0)&&(n<5)) return a[n];
else return Nothing(A);
}
};
int main()
{
B b;
for (int i=3;i<7;i++)
{
A &ra=b.GetA(i);
if (!&ra) std::cout << i << ": ra=nothing\n";
else std::cout << i << ": ra=" << ra.i << "\n";
}
return 0;
}
The macro Nothing(Type) returns a value, in this case that represented by nullptr - you can as well use 0, to which the reference's address is set. This address can now be checked as-if you have been using pointers.
From C++17 on, you can use the native std::optional (here) in the following way:
std::optional<SomeResource> SomeClass::getSomething(std::string name) {
if (content_.find(name) != content_.end()) return content_[name];
return std::nullopt;
}
Here are a couple of ideas:
Alternative 1:
class Nullable
{
private:
bool m_bIsNull;
protected:
Nullable(bool bIsNull) : m_bIsNull(bIsNull) {}
void setNull(bool bIsNull) { m_bIsNull = bIsNull; }
public:
bool isNull();
};
class SomeResource : public Nullable
{
public:
SomeResource() : Nullable(true) {}
SomeResource(...) : Nullable(false) { ... }
...
};
Alternative 2:
template<class T>
struct Nullable<T>
{
Nullable(const T& value_) : value(value_), isNull(false) {}
Nullable() : isNull(true) {}
T value;
bool isNull;
};
Yet another option - one that I have used from time to time for when you don't really want a "null" object returned but instead an "empty/invalid" object will do:
// List of things
std::vector<some_struct> list_of_things;
// An emtpy / invalid instance of some_struct
some_struct empty_struct{"invalid"};
const some_struct &get_thing(int index)
{
// If the index is valid then return the ref to the item index'ed
if (index <= list_of_things.size())
{
return list_of_things[index];
}
// Index is out of range, return a reference to the invalid/empty instance
return empty_struct; // doesn't exist
}
Its quite simple and (depending on what you are doing with it at the other end) can avoid the need to do null pointer checks on the other side. For example if you are generating some lists of thing, e.g:
for (const auto &sub_item : get_thing(2).sub_list())
{
// If the returned item from get_thing is the empty one then the sub list will
// be empty - no need to bother with nullptr checks etc... (in this case)
}