Preventing the creation of a copy and assigning a reference to the return value

If I have a function that returns a reference to an instance of a class that I do not have above its source, say list<int>:

list<int>& f();

I want to make sure that its value is assigned only to another link, for example:

list<int> &a_list = f();

If the user should have done this:

list<int> a_list = f(); // note: no '&', so the list is copied

I want this to be a compile-time error, as the user will only manipulate a copy of the list, not the original list (which is never intended for my application).

Is there a way to prevent the creation of a copy and assignment in the above (say, through some kind of "wrapper" class)?

Ideally, if you used some wrapper class, say wrapper<T>, I would like it to work for objects of any type T.


, , , , - private :

class MyClass {
public:
    // ...
private:
    MyClass( MyClass const& );
    MyClass operator=( MyClass const& );
};

; , , , , std::list, - private.

+3
5

, . - , .

: , , T&, T. , , ( !) - .

+2

, . , → . , , , , . , , .

+1

(, , ), . boost:: noncopyable, . / .

EDIT: , , , , / , .

, , , , , ( , , ). .

+1

, -, . , , , .

OTOH, , . , Uncopyable , . ( , , , .)

#include <iostream>
#include <list>

template <typename T>
class Uncopyable
{
public:
    Uncopyable(T& r) : ref(r) {}

    T* operator->() { return &ref; }

private:
    T& ref;
};

Uncopyable<std::list<int> > get_list()
{
    static std::list<int> l;
    l.push_back(l.size());
    return l;
}

int main() 
{
    for (int i = 0; i < 10; ++i)
    {
        Uncopyable<std::list<int> > my_l = get_list();
        std::cout << my_l->size() << std::endl;
    }
}
+1

, . , - , - .

, , , . , , ++.

[Edit] , - . :

template <class T>
class NoncopyablePtr
{
private:
    T* ptr;

public:
    /*implicit*/ NoncopyablePtr(T* iptr): ptr(iptr) {}

    T* operator->() const
    {
        return ptr;
    }
};

This would make it very difficult for the user to copy the pointer. They will have to call operator-> explicitly and cast the result. Now just return NoncopyablePtr <stand :: List <int → and you will make it terribly tough for clients (but not impossible) to make a copy of this list.

If you do not like to use operator->, then I am afraid that there is no other way to prevent the ability to easily copy the result.

+1
source

Source: https://habr.com/ru/post/1751484/


All Articles