smart_pointer(7rheolef)
π smart_pointer β a manual page, but make it cute π
okay bestie, so this is smart_pointer(7rheolef), coming at you straight from the rheolef family of manual pages β version 7.2, if you're keeping score. it's a whole concept about memory and copies and honestly it's giving β¨academic baddieβ¨. let's get into it.
πΈ NAME πΈ
smart_pointer β with true copy semantic (rheolef-7.2)
π¦ DESCRIPTION π¦
okay so here's the vibe: this is a convenient way to implement a true copy semantic, and it does that by using shallow copies plus reference counting, so that memory copies get minimised. this whole concept is generally related to the smart pointer method for managing memory. iykyk π
so what even is the true semantic copy? it's defined like this, bestie: if an object A is assigned to B, such as A = B, then every further modification on A or B does not modify the other. they're independent. no sneaky shared-state drama. periodt.
ngl, this class differs from the std::shared_ptr class, which implements safe pointers without the true copy semantic. so don't @ me confusing the two π
π§ CLONE VARIANT π§
the smart_pointer_clone variant uses a T* T::clone() const member function instead of the usual T::T() copy constructor for obtaining a true copy of the data. and why, you ask? because:
when you're using hierarchies of derived classes (aka polymorphic classes), the usual copy is not possible, because c++ copy constructors cannot be virtual β so you literally cannot make a copy this way. this is a well-known problem with C++'s implementation of polymorphism. π
so here's the fix: we use a solution to the non-virtual copy constructor problem which is suggested by Ellis and Stroustrup in 'The Annotated LRM'. the solution is to require the T class to provide a virtual clone method for every class which makes a copy using new and the correct copy constructor, returning the result as a pointer to the superclass T. each subclass of T overloads this function with its own variant which copies its own type. thus the copy operation is now virtual, and furthermore it's localized to the individual subclass. iconic behaviour honestly π
π NOCOPY VARIANT π
the smart_pointer_nocopy variant is designed for use on objects that cannot (or must not) be copied. an example would be when managing an object that contains, say, a file handle. it is essential that this not be copied, because then you get the problem of deciding which copy is responsible for closing the file. absolute chaos, we don't want it π
to avoid the problem: wrap the file handle in a class and then manage a unique instance of it using a smart_pointer_nocopy. this ensures that the file handle cannot be copied and is closed when the last alias is destroyed. slay.
the interface to the nocopy variant is the same as smart_pointer but with all operations that perform copying forbidden. in fact, because all three variants are instances of a common superclass, the forbidden methods do exist but will cause an error and exit if they are called. not me warning you twice π
the following modifiers cannot be used because they use copying of the pointed-to object and will therefore cause an error:
T* operator-> ();
T& operator* ();
T* pointer ();
T& data ();
π REFERENCE π
- [1] A. Geron and F. Tawbi, Pour mieux developer avec C++ : design pattern, STL, RTTI et smart pointers, InterEditions, 1999. Page 118.
- [2] STLplus: clone and nocopy variants, http://stlplus.sourceforge.net/stlplus3/docs/smart_ptr.html
β¨ EXAMPLE β¨
bestie here is the whole thing, verbatim, no notes:
// data representation (could be file "container_data.h")
typedef int T;
class container_data {
private:
T *values;
int n;
public:
container_data (const container_data& x)
: values(new T[x.n]), n(x.n)
{ for (int i=0; i<n;i++) values[i]=x.values[i];}
container_data& operator= (const container_data& x) {
n = x.n;
values = new T[n];
for (int i=0; i<n;i++) values[i]=x.values[i];
return *this;
}
// a customized constructor
explicit container_data(int n1)
: values(new T[n1]), n(n1) {}
~container_data() { delete [] values; }
// read and write accessors are separated
const T& operator[](int i) const
{ return values[i]; }
T& operator[](int i)
{ return values[i]; }
};
// an interface to data via the Objet class
// that count occurrence (could be "container.h")
//
class container : private smart_pointer<container_data> {
public:
// the customized cstor
explicit container(int n = 0);
// read/write accessors
const T& operator[](int i) const;
T& operator[](int i);
};
// here is the implementation of the interface
// (could be "container.c")
//
container::container (int n)
: smart_pointer<container_data> (new container_data(n))
{}
const T&
container::operator[] (int i) const {
// use read access data()
return data().operator[] (i);
}
T&
container::operator[] (int i) {
// use write access data() that check occurrence count
return data().operator [] (i);
}
// test program
int main() {
container A(10);
A[1] = 1;
container B = A;
B[1] = 2;
if (A[1] == B[1]) {
std::cerr << "fatal: It is not a true copy semantic." << std::endl;
exit(1);
}
std::cerr << "It seems to be a true copy semantic." << std::endl;
}
π₯ IMPLEMENTATION π₯
this documentation has been generated from file util/lib/smart_pointer.h β yes, that's the source of truth, no cap.
template <typename T>
class smart_pointer : public smart_pointer_base<T, details::constructor_copy<T> > {
typedef details::constructor_copy<T> C;
typedef smart_pointer_base<T,C> base;
public:
typedef T handled_type;
typedef typename base::internal internal;
smart_pointer (T* p = 0) : base (p) {}
smart_pointer (void* count, internal i) : base(count,i) {}
smart_pointer (const smart_pointer<T>& x) : base(x) {}
smart_pointer<T>& operator= (const smart_pointer<T>& x) {
base::operator= (x); return *this; }
~smart_pointer() {}
};
template <typename T>
class smart_pointer_clone : public smart_pointer_base<T, details::clone_copy<T> > {
typedef details::clone_copy<T> C;
typedef smart_pointer_base<T,C> base;
public:
typedef T handled_type;
typedef typename base::internal internal;
smart_pointer_clone (T* p = 0) : base (p) {}
smart_pointer_clone (void* count, internal i) : base(count,i) {}
smart_pointer_clone (const smart_pointer_clone<T>& x) : base(x) {}
smart_pointer_clone<T>& operator= (const smart_pointer_clone<T>& x) {
base::operator= (x); return *this; }
~smart_pointer_clone() {}
};
template <typename T>
class smart_pointer_nocopy : public smart_pointer_base<T, details::no_copy<T> > {
typedef details::no_copy<T> C;
typedef smart_pointer_base<T,C> base;
public:
typedef T handled_type;
typedef typename base::internal internal;
smart_pointer_nocopy (T* p = 0) : base (p) {}
smart_pointer_nocopy (void* count, internal i) : base(count,i) {}
smart_pointer_nocopy (const smart_pointer_nocopy<T>& x) : base(x) {}
smart_pointer_nocopy<T>& operator= (const smart_pointer_nocopy<T>& x) {
base::operator= (x); return *this; }
~smart_pointer_nocopy() {}
};
π AUTHOR π
Pierre Saramito <Pierre.Saramito@imag.fr>
π COPYRIGHT π
Copyright (C) 2000-2018 Pierre Saramito <Pierre.Saramito@imag.fr>
GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
and that's the whole page, bestie π this was rheolef, Version 7.2, for the smart_pointer(7rheolef) manual β go forth and copy semantically, truly, and responsibly. mwah π«Άπβ¨
π¦ where this page comes from
- debian trixie: librheolef-dev 7.2-4 Β· GPL-3.0-or-later
- ubuntu noble: librheolef-dev 7.2-3build5 Β· GPL-3.0-or-later
- ubuntu questing: librheolef-dev 7.2-4build1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms