473,850 Members | 2,111 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Deep Copy smart pointer not requiring virtual copy constructor

A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.
I need help with checking that it was exception safe and exception
neutral/
I got a reply from Bux with his code for a smart pointer with far fewer
lines of code
and more cleaner design, not over engineered like mine.

http://groups.google.co.uk/group/com...e5c18bc6bb5c7e
However there was one possible extension to that code :

'The trade-off is that copy_ptr<Basean d copy_ptr<Derive dare
unrelated '
Kai-Uwe Bux
I think I have managed to implement this extension, so I post my code
here along with a main.cpp that exhibists the extension.

Any comments about my abuse of the language would be more than welcome
--------------------------------------------------------------------------------------------------------------
<smart_ptr_poli cies.h>
#ifndef SMART_POINTER_P OLICIES_HEADER
#define SMART_POINTER_P OLICIES_HEADER
#include<algori thm>
#include<boost/utility.hpp>
#include<boost/type_traits.hpp >

//
http://groups.google.co.uk/group/com...hread/thread/b...

template<class DerivedClass>
void * Buxclone(const void *theOtherPtr){
return new DerivedClass(*s tatic_cast<cons t
DerivedClass*>( theOtherPtr));
}
template<class BaseClass>
struct BuxWrappedPoint er {

template<class T>
friend struct BuxWrappedPoint er;

BuxWrappedPoint er():raw_pointe r(0),theCloner( 0){}

template<class DerivedClass>
BuxWrappedPoint er(DerivedClass * ptr):raw_pointe r(ptr),
theCloner(&Buxc lone<DerivedCla ss>){}
BuxWrappedPoint er(const BuxWrappedPoint er &theOther):
theCloner(theOt her.theCloner),
raw_pointer(the Other.clone(the Other.raw_point er)){}

template<class MiddleBase>
BuxWrappedPoint er(const BuxWrappedPoint er<MiddleBase>
&theMiddleBa se,
typename
boost::enable_i f<boost::is_bas e_of<BaseClass, MiddleBase>,Mid dleBase>::type
*pp=0):
theCloner(theMi ddleBase.theClo ner),
raw_pointer(sta tic_cast<BaseCl ass *>
(theMiddleBase. theCloner(stati c_cast<const BaseClass
*>(theMiddleBas e.raw_pointer)) )){}

BuxWrappedPoint er<BaseClass& operator=(const
BuxWrappedPoint er<BaseClass&th eOther)
{
BuxWrappedPoint er<BaseClasstem p(theOther);
std::swap(temp. raw_pointer,raw _pointer);
return *this;
}
BaseClass * raw_pointer;
~BuxWrappedPoin ter(){delete raw_pointer;}
private:
BaseClass *clone(const BaseClass * theSource)const {
return static_cast<Bas eClass*>(theClo ner(static_cast <const
BaseClass*>(the Source)));
}
typedef void * (*clone_)(const void *);
clone_ theCloner;
};
#endif
--------------------------------------------------------------------------------------------------------------
<smart_ptr.h>

#ifndef SMART_POINTER__ HEADER
#define SMART_POINTER__ HEADER

#include"smart_ ptr_policies.h"

template<
class BaseClass,
template <classclass CLONE_POLICY
>
class smart_ptr {
public:
typedef typename boost::remove_c onst<BaseClass> ::type non_const_base;

template<class T,template <classclass CLONE_POLICY >
friend class smart_ptr;

template<class DerivedClass>
smart_ptr(Deriv edClass *
theDerivedPoint er_):theWrapped Pointer(theDeri vedPointer_){}

smart_ptr(const smart_ptr<non_c onst_base,CLONE _POLICY>&
theOtherSmart_p tr):
theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer){}

smart_ptr(const smart_ptr<const non_const_base, CLONE_POLICY>&
theOtherSmart_p tr):
theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer){}

template<class T>
smart_ptr(const smart_ptr<T,CLO NE_POLICY>& theOtherSmart_p tr,
typename boost::enable_i f<boost::is_bas e_of<non_const_ base,typename
boost::remove_c onst<T>::type>, T>::type *pp=0):
theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer){}

smart_ptr(){}

BaseClass *operator->()const{retu rn
theWrappedPoint er.raw_pointer; }

virtual ~smart_ptr(){}
private:
smart_ptr & operator=(const BaseClass *ptr);

CLONE_POLICY<no n_const_basethe WrappedPointer;
};
#endif
--------------------------------------------------------------------------------------------------------------
<main.cpp>
#include<vector >
#include<iostre am>

#include<cctype >
#include"smart_ ptr.h"

using namespace std;
class Base {
public:
Base():ch('*'){
Count++;
}
Base(const Base&):ch('*'){
Count++;
}
virtual char show(){
return ch;
}
virtual ~Base(){Count--;}
virtual void v()const=0;
static unsigned long Count;
private:
char ch;
};
unsigned long Base::Count(0);

/// this will give us lots of derived classes
template<char ch_>
class Derived :public Base {
public:
Derived():ch(ch _){
Count++;
}
Derived(const Derived<ch_>&): ch(ch_){
Count++;
}
virtual char show(){
return ch;
}
virtual ~Derived(){Coun t--;}
virtual void v()const{}
static unsigned long Count;
private:
char ch;

};
template<char ch_>
unsigned long Derived<ch_>::C ount(0);

template<char ch_>
class DerivedSquared :public Derived<ch_{
public:
DerivedSquared( ):ch(std::tolow er(ch_)){
Count++;
}
DerivedSquared( const DerivedSquared< ch_>&):ch(std:: tolower(ch_)){
Count++;
}
virtual char show(){return ch;}
virtual ~DerivedSquared (){Count--;}
virtual void v()const{}
static unsigned long Count;
private:
char ch;

};
template<char ch_>
unsigned long DerivedSquared< ch_>::Count(0);


int main() {

smart_ptr<Deriv ed<'B'>,BuxWrap pedPointertheDP A(new
DerivedSquared< 'B'>);
cout << theDPA->show();

smart_ptr<Base, BuxWrappedPoint ertheDPA2(theDP A);
cout << theDPA2->show();
}
-------------------------------------------------------------------------------------------------------------------------
NSC

Nov 12 '06 #1
11 3442
Ni*****@yahoo.c o.uk wrote:
A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.
I need help with checking that it was exception safe and exception
neutral/
I got a reply from Bux with his code for a smart pointer with far fewer
lines of code
and more cleaner design, not over engineered like mine.

http://groups.google.co.uk/group/com...e5c18bc6bb5c7e
However there was one possible extension to that code :

'The trade-off is that copy_ptr<Basean d copy_ptr<Derive dare
unrelated '
Kai-Uwe Bux
I think I have managed to implement this extension, so I post my code
here along with a main.cpp that exhibists the extension.
Why do you need such a beast ? i.e. what are the requirements and use case ?
>
Any comments about my abuse of the language would be more than welcome
It's kind of hard to read.
Nov 12 '06 #2
Ni*****@yahoo.c o.uk wrote:
A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.
I need help with checking that it was exception safe and exception
neutral/
I got a reply from Bux with his code for a smart pointer with far fewer
lines of code
and more cleaner design, not over engineered like mine.

http://groups.google.co.uk/group/com...e5c18bc6bb5c7e
>

However there was one possible extension to that code :

********'The trade-off is that *copy_ptr<Basea nd copy_ptr<Derive dare
unrelated '
Kai-Uwe Bux
I think I have managed to implement this extension, so I post my code
here along with a main.cpp that exhibists the extension.
What a coincidence, your post prompted me to rethink that, too. I appears
that we arrived at very similar conclusions (see below).

Any comments about my abuse of the language would be more than welcome
General comment: you lines are too long.

--------------------------------------------------------------------------------------------------------------
<smart_ptr_poli cies.h>
#ifndef SMART_POINTER_P OLICIES_HEADER
#define SMART_POINTER_P OLICIES_HEADER
#include<algori thm>
#include<boost/utility.hpp>
#include<boost/type_traits.hpp >

//
http://groups.google.co.uk/group/com...hread/thread/b...

template<class DerivedClass>
void * Buxclone(const void *theOtherPtr){
* * * * * * * * return new DerivedClass(*s tatic_cast<cons t
DerivedClass*>( theOtherPtr));
}
template<class BaseClass>
struct BuxWrappedPoint er {

******** * template<class T>
******** * friend *struct BuxWrappedPoint er;

* * * *BuxWrappedPoin ter():raw_point er(0),theCloner (0){}

* * * *template<class DerivedClass>
* * * * * * *BuxWrappedPoin ter(DerivedClas s * ptr):raw_pointe r(ptr),
*************** *************** ** theCloner(&Buxc lone<DerivedCla ss>){}
* * * *BuxWrappedPoin ter(const BuxWrappedPoint er &theOther):
*************** ********* theCloner(theOt her.theCloner),
*************** *************** **
*************** *************** **raw_pointer(t heOther.clone(t heOther.raw_poi nter))
*************** *************** **{}

******** * template<class MiddleBase>
******** * BuxWrappedPoint er(const BuxWrappedPoint er<MiddleBase>
&theMiddleBa se,
*************** *************** **typename
boost::enable_i f<boost::is_bas e_of<BaseClass, MiddleBase>,Mid dleBase>::type
*pp=0):
*************** *************** **********theCl oner(theMiddleB ase.theCloner),
*************** *************** **********raw_p ointer(static_c ast<BaseClass
*>
*************** *************** *************** ***(theMiddleBa se.theCloner(st atic_cast<const
BaseClass
*>(theMiddleBas e.raw_pointer)) )){}

* * * *BuxWrappedPoin ter<BaseClass& operator=(const
BuxWrappedPoint er<BaseClass&th eOther)
******** * {
*************** * * BuxWrappedPoint er<BaseClasstem p(theOther);
* * * * * *std::swap(temp .raw_pointer,ra w_pointer);
* * * * * *return *this;
******** * }
* * * BaseClass * raw_pointer;
* * *~BuxWrappedPoi nter(){delete raw_pointer;}
private:
******** *BaseClass *clone(const BaseClass * theSource)const {
*************** *return static_cast<Bas eClass*>(theClo ner(static_cast <const
BaseClass*>(the Source)));
******** *}
* * * typedef void * (*clone_)(const void *);
* * * clone_ *theCloner;
};
#endif
--------------------------------------------------------------------------------------------------------------
Oh boy, you are quite boost-savvy! I do not quite see, however, what all
this enable_if< ... stuff is doing for you. If it is just to get the
right compiler errors if you do

copy_ptr< Base b_ptr = copy_ptr< NotDerived >( new not Derived() );

then, I think, there are simpler means of going about it (see below). But I
might be missing something here.
<smart_ptr.h>

#ifndef SMART_POINTER__ HEADER
#define SMART_POINTER__ HEADER

#include"smart_ ptr_policies.h"

template<
* * * * class BaseClass,
* * * * template <classclass CLONE_POLICY
class smart_ptr {
public:
*************** *typedef typename boost::remove_c onst<BaseClass> ::type
*************** *non_const_base ;

*************** *template<class T,template <classclass CLONE_POLICY >
*************** *friend class smart_ptr;
g++ gives me an error for the above saying that the declaration of
CLONE_POLICY shadows the template parameter.
>
* * * * template<class DerivedClass>
* * * * * * *smart_ptr(Deri vedClass *
theDerivedPoint er_):theWrapped Pointer(theDeri vedPointer_){}

*************** *smart_ptr(cons t smart_ptr<non_c onst_base,CLONE _POLICY>&
theOtherSmart_p tr):
*************** *********
*************** *********theWra ppedPointer(the OtherSmart_ptr. theWrappedPoint er)
*************** *********{}

*************** *smart_ptr(cons t smart_ptr<const
*************** *non_const_base ,CLONE_POLICY>&
theOtherSmart_p tr): *************** *********
*************** *********theWra ppedPointer(the OtherSmart_ptr. theWrappedPoint er)
*************** *********{}

*************** *template<class T>
*************** *********smart_ ptr(const smart_ptr<T,CLO NE_POLICY>&
*************** *********theOth erSmart_ptr,
*************** *************** **typename
*************** *************** **boost::enable _if<boost::is_b ase_of<non_cons t_base,typename
boost::remove_c onst<T>::type>, T>::type
*pp=0):
*************** *************** **********theWr appedPointer(th eOtherSmart_ptr .theWrappedPoin ter)
*************** *************** **********{}

* * * * smart_ptr(){}

* * * * BaseClass *operator->()const{retu rn
theWrappedPoint er.raw_pointer; }

*************** *virtual ~smart_ptr(){}
Why is this destructor virtual?
>

private:
* * * * smart_ptr & operator=(const BaseClass *ptr);

* * * * CLONE_POLICY<no n_const_basethe WrappedPointer;
};
#endif
Again, I find the boost stuff confusing. What design specs necessitate the
use of non_const_base and remove_const?
<main.cpp>
#include<vector >
#include<iostre am>

#include<cctype >
#include"smart_ ptr.h"

using namespace std;
class Base {
public:
********Base(): ch('*'){
*************** *Count++;
********}
********Base(co nst Base&):ch('*'){
*************** *Count++;
********}
********virtual char show(){
*************** *return ch;
********}
********virtual ~Base(){Count--;}
********virtual void v()const=0;
********static unsigned long Count;
private:
********char ch;
};
unsigned long Base::Count(0);

/// this will give us lots of derived classes
template<char ch_>
class Derived :public Base {
public:
********Derived ():ch(ch_){
*************** *Count++;
********}
********Derived (const Derived<ch_>&): ch(ch_){
*************** *Count++;
********}
********virtual char show(){
*************** *return ch;
********}
********virtual ~Derived(){Coun t--;}
********virtual void v()const{}
********static unsigned long Count;
private:
********char ch;

};
template<char ch_>
unsigned long Derived<ch_>::C ount(0);

template<char ch_>
class DerivedSquared :public Derived<ch_{
public:
********Derived Squared():ch(st d::tolower(ch_) ){
*************** *Count++;
********}
********Derived Squared(const DerivedSquared< ch_>&):ch(std:: tolower(ch_)){
*************** *Count++;
********}
********virtual char show(){return ch;}
********virtual ~DerivedSquared (){Count--;}
********virtual void v()const{}
********static unsigned long Count;
private:
********char ch;

};
template<char ch_>
unsigned long DerivedSquared< ch_>::Count(0);


int main() {

********smart_p tr<Derived<'B'> ,BuxWrappedPoin tertheDPA(new
DerivedSquared< 'B'>);
********cout << theDPA->show();

********smart_p tr<Base,BuxWrap pedPointertheDP A2(theDPA);
********cout << theDPA2->show();
}
I found that

smart_ptr<inti_ ptr ( new int ( 5 ) );
cout << *i_ptr << '\n';

gives me an error. You should add operator*.

I worked a little on the non-policy based version to have copy_ptr<Basean d
copy_ptr<Derive dbehave as desired. I also added a compile time check
agains using non-polymorphic base classes. This might be overkill.
(Alternatively, one could think about adding a deleter-function that would
use the right destructor in any case.)
#include <algorithm// std::swap

template < typename T >
struct non_polymorphic _class_error {
enum {
trigger = sizeof( dynamic_cast<vo id*>( static_cast<T*> (0) ) )
};

};
// The clone function:
// =============== ====
template < typename T >
void * clone ( void * ptr ) {
return ( ptr == 0 ? 0
: static_cast<voi d*>
( new T ( *( static_cast<T*> ( ptr ) ) ) ) );
}

// The copy_ptr:
// =============

template < typename T >
class copy_ptr {

friend void swap ( copy_ptr<T& p, copy_ptr<T& q ) {
std::swap( p.raw_ptr, q.raw_ptr );
std::swap( p.clone_fct, q.clone_fct );
}

template < typename D >
friend class copy_ptr;

/*
The idea is that in addition to a pointer, we also need
a pointer to the _appropriate_ clone function.
*/
T * raw_ptr;
void * ( *clone_fct ) ( void * );

public:

copy_ptr ( T * ptr = 0)
: raw_ptr ( ptr )
, clone_fct ( clone<T)
{}

template < typename D >
copy_ptr ( D * ptr )
: raw_ptr ( ptr )
, clone_fct ( clone<D)
{
non_polymorphic _class_error<Td 2;
}

// copy construction clones:
copy_ptr ( copy_ptr const & other )
: raw_ptr ( static_cast<T*> ( other.clone_fct ( other.raw_ptr ) ) )
, clone_fct ( other.clone_fct )
{}

template < typename D >
copy_ptr ( copy_ptr<Dconst & other )
: raw_ptr ( static_cast<D*> ( other.clone_fct ( other.raw_ptr ) ) )
, clone_fct ( other.clone_fct )
{
non_polymorphic _class_error<Td 2;
}

// destruction frees the pointee
~copy_ptr ( void ) {
delete ( raw_ptr );
}

// assignment reduces to copy construction
// (for correctness and exception safety):
copy_ptr & operator= ( copy_ptr const & other ) {
copy_ptr dummy ( other );
swap( *this, dummy );
return( *this );
}

template < typename D >
copy_ptr & operator= ( copy_ptr<Dconst & other ) {
copy_ptr dummy ( other );
swap( *this, dummy );
return( *this );
}

T const * operator-( void ) const {
return( raw_ptr );
}

T * operator-( void ) {
return( raw_ptr );
}

T const & operator* ( void ) const {
return( *( this->operator->() ) );
}

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

}; // copy_ptr<T>

Please, let me know what you think.
Best

Kai-Uwe Bux
Nov 12 '06 #3

Kai-Uwe Bux wrote:
Ni*****@yahoo.c o.uk wrote:
A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.
I need help with checking that it was exception safe and exception
neutral/
I got a reply from Bux with his code for a smart pointer with far fewer
lines of code
and more cleaner design, not over engineered like mine.
http://groups.google.co.uk/group/com...e5c18bc6bb5c7e


However there was one possible extension to that code :

'The trade-off is that copy_ptr<Basean d copy_ptr<Derive dare
unrelated '
Kai-Uwe Bux
I think I have managed to implement this extension, so I post my code
here along with a main.cpp that exhibists the extension.

What a coincidence, your post prompted me to rethink that, too. I appears
that we arrived at very similar conclusions (see below).

Any comments about my abuse of the language would be more than welcome

General comment: you lines are too long.
I apologise for the length of the lines, I think my problem is 2-fold.
Firstly I am not a proffesional developer
I have never really learnt a good style for code presentation, but I
suppose tools like doxygen make that a
non-excuse. Secondly, I think something just went wrong with the
pasting.
>
--------------------------------------------------------------------------------------------------------------
<smart_ptr_poli cies.h>
#ifndef SMART_POINTER_P OLICIES_HEADER
#define SMART_POINTER_P OLICIES_HEADER
#include<algori thm>
#include<boost/utility.hpp>
#include<boost/type_traits.hpp >

//
http://groups.google.co.uk/group/com...hread/thread/b...

template<class DerivedClass>
void * Buxclone(const void *theOtherPtr){
return new DerivedClass(*s tatic_cast<cons t
DerivedClass*>( theOtherPtr));
}
template<class BaseClass>
struct BuxWrappedPoint er {

template<class T>
friend struct BuxWrappedPoint er;

BuxWrappedPoint er():raw_pointe r(0),theCloner( 0){}

template<class DerivedClass>
BuxWrappedPoint er(DerivedClass * ptr):raw_pointe r(ptr),
theCloner(&Buxc lone<DerivedCla ss>){}
BuxWrappedPoint er(const BuxWrappedPoint er &theOther):
theCloner(theOt her.theCloner),

raw_pointer(the Other.clone(the Other.raw_point er))
{}

template<class MiddleBase>
BuxWrappedPoint er(const BuxWrappedPoint er<MiddleBase>
&theMiddleBa se,
typename
boost::enable_i f<boost::is_bas e_of<BaseClass, MiddleBase>,Mid dleBase>::type
*pp=0):
theCloner(theMi ddleBase.theClo ner),
raw_pointer(sta tic_cast<BaseCl ass
*>
(theMiddleBase. theCloner(stati c_cast<const
BaseClass
*>(theMiddleBas e.raw_pointer)) )){}

BuxWrappedPoint er<BaseClass& operator=(const
BuxWrappedPoint er<BaseClass&th eOther)
{
BuxWrappedPoint er<BaseClasstem p(theOther);
std::swap(temp. raw_pointer,raw _pointer);
return *this;
}
BaseClass * raw_pointer;
~BuxWrappedPoin ter(){delete raw_pointer;}
private:
BaseClass *clone(const BaseClass * theSource)const {
return static_cast<Bas eClass*>(theClo ner(static_cast <const
BaseClass*>(the Source)));
}
typedef void * (*clone_)(const void *);
clone_ theCloner;
};
#endif
--------------------------------------------------------------------------------------------------------------

Oh boy, you are quite boost-savvy! I do not quite see, however, what all
this enable_if< ... stuff is doing for you. If it is just to get the
right compiler errors if you do

copy_ptr< Base b_ptr = copy_ptr< NotDerived >( new not Derived() );

then, I think, there are simpler means of going about it (see below). But I
might be missing something here.
re enable_if from the boost website

The enable_if family of templates is a set of tools
to allow a function template or a class
template specialization to include or exclude itself
from a set of matching functions or
specializations based on properties of its template
arguments. For example, one can define
function templates that are only enabled for, and
thus only match, an arbitrary set of types
defined by a traits class. The enable_if templates
can also be applied to enable class template
specializations .

So I am only enabling
BuxWrappedPoint er(const BuxWrappedPoint er<MiddleBase>
&theMiddleBa se)

when MiddleBase is derived FROM Base. This allows :
clone_ptr<Middl eBasetheMiddleC lass_ptr(new Derived);
clone_ptr<Baset heBaseClass_ptr (theMiddleClass _ptr); //
casting up the hierachy should be allowed

but disallows everything else including
clone_ptr<Baset heBaseClass_ptr (new Derived);
clone_ptr<Middl eBasetheMiddleB aseClass_ptr
(theMiddleClass _ptr); // casting down the hierachy should NOT be
allowed

<smart_ptr.h>

#ifndef SMART_POINTER__ HEADER
#define SMART_POINTER__ HEADER

#include"smart_ ptr_policies.h"

template<
class BaseClass,
template <classclass CLONE_POLICY
>
class smart_ptr {
public:
typedef typename boost::remove_c onst<BaseClass> ::type
non_const_base;

template<class T,template <classclass CLONE_POLICY >
friend class smart_ptr;

g++ gives me an error for the above saying that the declaration of
CLONE_POLICY shadows the template parameter.

template<class DerivedClass>
smart_ptr(Deriv edClass *
theDerivedPoint er_):theWrapped Pointer(theDeri vedPointer_){}

smart_ptr(const smart_ptr<non_c onst_base,CLONE _POLICY>&
theOtherSmart_p tr):

theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer)
{}

smart_ptr(const smart_ptr<const
non_const_base, CLONE_POLICY>&
theOtherSmart_p tr):
theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer)
{}

template<class T>
smart_ptr(const smart_ptr<T,CLO NE_POLICY>&
theOtherSmart_p tr,
typename
boost::enable_i f<boost::is_bas e_of<non_const_ base,typename
boost::remove_c onst<T>::type>, T>::type
*pp=0):
theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer)
{}

smart_ptr(){}

BaseClass *operator->()const{retu rn
theWrappedPoint er.raw_pointer; }

virtual ~smart_ptr(){}

Why is this destructor virtual?


private:
smart_ptr & operator=(const BaseClass *ptr);

CLONE_POLICY<no n_const_basethe WrappedPointer;
};
#endif

Again, I find the boost stuff confusing. What design specs necessitate the
use of non_const_base and remove_const?
This non_const_base gives me 'type' from 'const type'
So this allows me to do :
copy_ptr<Baseth ePtr(new Derived);
copy_ptr<const BasetheConstPtr (thePtr);

Of course this may not be so important for deep copy but may be useful
for other policies. But I still want the Policy
class to be template on Base, even if the smart_ptr is templated on
Base or const Base, in some sense they are the same.

The line
template<class T>
smart_ptr(const smart_ptr<T,CLO NE_POLICY>&

should be something like

template<class T, template <classclass OTHER_CLONE_POL ICY>
smart_ptr(const
smart_ptr<T,OTH ER_CLONE_POLICY >&

sorry, I use both Linux gcc and msvc, and I happend to be using msvc at
that moment, and it did not complain.

Again I am using the boost template stuff ONLY when T is derived FROM
Base, for same reasons as above. But I m ripping of the const of them
before I compare. That is

BaseClass = Base T = MiddleBase
This is ok
BaseClass = const Base T = MiddleBase
This is ok
BaseClass = Base T = const MiddleBase
This is ok
BaseClass = const Base T = const
MiddleBase This is ok

<main.cpp>
#include<vector >
#include<iostre am>

#include<cctype >
#include"smart_ ptr.h"

using namespace std;
class Base {
public:
Base():ch('*'){
Count++;
}
Base(const Base&):ch('*'){
Count++;
}
virtual char show(){
return ch;
}
virtual ~Base(){Count--;}
virtual void v()const=0;
static unsigned long Count;
private:
char ch;
};
unsigned long Base::Count(0);

/// this will give us lots of derived classes
template<char ch_>
class Derived :public Base {
public:
Derived():ch(ch _){
Count++;
}
Derived(const Derived<ch_>&): ch(ch_){
Count++;
}
virtual char show(){
return ch;
}
virtual ~Derived(){Coun t--;}
virtual void v()const{}
static unsigned long Count;
private:
char ch;

};
template<char ch_>
unsigned long Derived<ch_>::C ount(0);

template<char ch_>
class DerivedSquared :public Derived<ch_{
public:
DerivedSquared( ):ch(std::tolow er(ch_)){
Count++;
}
DerivedSquared( const DerivedSquared< ch_>&):ch(std:: tolower(ch_)){
Count++;
}
virtual char show(){return ch;}
virtual ~DerivedSquared (){Count--;}
virtual void v()const{}
static unsigned long Count;
private:
char ch;

};
template<char ch_>
unsigned long DerivedSquared< ch_>::Count(0);


int main() {

smart_ptr<Deriv ed<'B'>,BuxWrap pedPointertheDP A(new
DerivedSquared< 'B'>);
cout << theDPA->show();

smart_ptr<Base, BuxWrappedPoint ertheDPA2(theDP A);
cout << theDPA2->show();
}

I found that

smart_ptr<inti_ ptr ( new int ( 5 ) );
cout << *i_ptr << '\n';

gives me an error. You should add operator*.
I completely agree, I should have posted a more complete class. But I
just wanted to show my extension to your trick
leaving out the other details. I intend to add other members too, such
as interoperabilit y with auto_ptr etc

>

I worked a little on the non-policy based version to have copy_ptr<Basean d
copy_ptr<Derive dbehave as desired. I also added a compile time check
agains using non-polymorphic base classes. This might be overkill.
(Alternatively, one could think about adding a deleter-function that would
use the right destructor in any case.)
#include <algorithm// std::swap

template < typename T >
struct non_polymorphic _class_error {
enum {
trigger = sizeof( dynamic_cast<vo id*>( static_cast<T*> (0) ) )
};

};
I forbid myslef from using dynamic_cast, but I would have to try to
remeber the reasons why. But I do have a question.
Isn't it true that dynamic_cast happens at runtime and therefore we
have a overhead, whereas static_cast takes place at compile time, so
we don't. I think the boost is_base combined with boost enable_if lets
us 'error check' at compile time.

>
// The clone function:
// =============== ====
template < typename T >
void * clone ( void * ptr ) {
return ( ptr == 0 ? 0
: static_cast<voi d*>
( new T ( *( static_cast<T*> ( ptr ) ) ) ) );
}

// The copy_ptr:
// =============

template < typename T >
class copy_ptr {

friend void swap ( copy_ptr<T& p, copy_ptr<T& q ) {
std::swap( p.raw_ptr, q.raw_ptr );
std::swap( p.clone_fct, q.clone_fct );
}

template < typename D >
friend class copy_ptr;

/*
The idea is that in addition to a pointer, we also need
a pointer to the _appropriate_ clone function.
*/
T * raw_ptr;
void * ( *clone_fct ) ( void * );

public:

copy_ptr ( T * ptr = 0)
: raw_ptr ( ptr )
, clone_fct ( clone<T)
{}

template < typename D >
copy_ptr ( D * ptr )
: raw_ptr ( ptr )
, clone_fct ( clone<D)
{
non_polymorphic _class_error<Td 2;
}

// copy construction clones:
copy_ptr ( copy_ptr const & other )
: raw_ptr ( static_cast<T*> ( other.clone_fct ( other.raw_ptr ) ) )
, clone_fct ( other.clone_fct )
{}

template < typename D >
copy_ptr ( copy_ptr<Dconst & other )
: raw_ptr ( static_cast<D*> ( other.clone_fct ( other.raw_ptr ) ) )
, clone_fct ( other.clone_fct )
{
non_polymorphic _class_error<Td 2;
}

// destruction frees the pointee
~copy_ptr ( void ) {
delete ( raw_ptr );
}

// assignment reduces to copy construction
// (for correctness and exception safety):
copy_ptr & operator= ( copy_ptr const & other ) {
copy_ptr dummy ( other );
swap( *this, dummy );
return( *this );
}

template < typename D >
copy_ptr & operator= ( copy_ptr<Dconst & other ) {
copy_ptr dummy ( other );
swap( *this, dummy );
return( *this );
}

T const * operator-( void ) const {
return( raw_ptr );
}

T * operator-( void ) {
return( raw_ptr );
}

T const & operator* ( void ) const {
return( *( this->operator->() ) );
}

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

}; // copy_ptr<T>

Please, let me know what you think.


I by no means am 'boost savy' I didn't even know about is_basr until a
few days ago. Its just that I find some real magical bits of
functionality there, its a waste of time trying to re-code some of it,
especially when the boost coders are in a far superior league to
of programmers to me. Also I prefer to do as much as possible at
compile time than at runtime.

N

PS I think my first ever use of is_base was to write this class.

Nov 12 '06 #4

Kai-Uwe Bux wrote:
Ni*****@yahoo.c o.uk wrote:
A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.
I need help with checking that it was exception safe and exception
neutral/
I got a reply from Bux with his code for a smart pointer with far fewer
lines of code
and more cleaner design, not over engineered like mine.
http://groups.google.co.uk/group/com...e5c18bc6bb5c7e


However there was one possible extension to that code :

'The trade-off is that copy_ptr<Basean d copy_ptr<Derive dare
unrelated '
Kai-Uwe Bux
I think I have managed to implement this extension, so I post my code
here along with a main.cpp that exhibists the extension.

What a coincidence, your post prompted me to rethink that, too. I appears
that we arrived at very similar conclusions (see below).

Any comments about my abuse of the language would be more than welcome

General comment: you lines are too long.

--------------------------------------------------------------------------------------------------------------
<smart_ptr_poli cies.h>
#ifndef SMART_POINTER_P OLICIES_HEADER
#define SMART_POINTER_P OLICIES_HEADER
#include<algori thm>
#include<boost/utility.hpp>
#include<boost/type_traits.hpp >

//
http://groups.google.co.uk/group/com...hread/thread/b...

template<class DerivedClass>
void * Buxclone(const void *theOtherPtr){
return new DerivedClass(*s tatic_cast<cons t
DerivedClass*>( theOtherPtr));
}
template<class BaseClass>
struct BuxWrappedPoint er {

template<class T>
friend struct BuxWrappedPoint er;

BuxWrappedPoint er():raw_pointe r(0),theCloner( 0){}

template<class DerivedClass>
BuxWrappedPoint er(DerivedClass * ptr):raw_pointe r(ptr),
theCloner(&Buxc lone<DerivedCla ss>){}
BuxWrappedPoint er(const BuxWrappedPoint er &theOther):
theCloner(theOt her.theCloner),

raw_pointer(the Other.clone(the Other.raw_point er))
{}

template<class MiddleBase>
BuxWrappedPoint er(const BuxWrappedPoint er<MiddleBase>
&theMiddleBa se,
typename
boost::enable_i f<boost::is_bas e_of<BaseClass, MiddleBase>,Mid dleBase>::type
*pp=0):
theCloner(theMi ddleBase.theClo ner),
raw_pointer(sta tic_cast<BaseCl ass
*>
(theMiddleBase. theCloner(stati c_cast<const
BaseClass
*>(theMiddleBas e.raw_pointer)) )){}

BuxWrappedPoint er<BaseClass& operator=(const
BuxWrappedPoint er<BaseClass&th eOther)
{
BuxWrappedPoint er<BaseClasstem p(theOther);
std::swap(temp. raw_pointer,raw _pointer);
return *this;
}
BaseClass * raw_pointer;
~BuxWrappedPoin ter(){delete raw_pointer;}
private:
BaseClass *clone(const BaseClass * theSource)const {
return static_cast<Bas eClass*>(theClo ner(static_cast <const
BaseClass*>(the Source)));
}
typedef void * (*clone_)(const void *);
clone_ theCloner;
};
#endif
--------------------------------------------------------------------------------------------------------------

Oh boy, you are quite boost-savvy! I do not quite see, however, what all
this enable_if< ... stuff is doing for you. If it is just to get the
right compiler errors if you do

copy_ptr< Base b_ptr = copy_ptr< NotDerived >( new not Derived() );

then, I think, there are simpler means of going about it (see below). But I
might be missing something here.
<smart_ptr.h>

#ifndef SMART_POINTER__ HEADER
#define SMART_POINTER__ HEADER

#include"smart_ ptr_policies.h"

template<
class BaseClass,
template <classclass CLONE_POLICY
>
class smart_ptr {
public:
typedef typename boost::remove_c onst<BaseClass> ::type
non_const_base;

template<class T,template <classclass CLONE_POLICY >
friend class smart_ptr;

g++ gives me an error for the above saying that the declaration of
CLONE_POLICY shadows the template parameter.

template<class DerivedClass>
smart_ptr(Deriv edClass *
theDerivedPoint er_):theWrapped Pointer(theDeri vedPointer_){}

smart_ptr(const smart_ptr<non_c onst_base,CLONE _POLICY>&
theOtherSmart_p tr):

theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer)
{}

smart_ptr(const smart_ptr<const
non_const_base, CLONE_POLICY>&
theOtherSmart_p tr):
theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer)
{}

template<class T>
smart_ptr(const smart_ptr<T,CLO NE_POLICY>&
theOtherSmart_p tr,
typename
boost::enable_i f<boost::is_bas e_of<non_const_ base,typename
boost::remove_c onst<T>::type>, T>::type
*pp=0):
theWrappedPoint er(theOtherSmar t_ptr.theWrappe dPointer)
{}

smart_ptr(){}

BaseClass *operator->()const{retu rn
theWrappedPoint er.raw_pointer; }

virtual ~smart_ptr(){}

Why is this destructor virtual?


private:
smart_ptr & operator=(const BaseClass *ptr);

CLONE_POLICY<no n_const_basethe WrappedPointer;
};
#endif

Again, I find the boost stuff confusing. What design specs necessitate the
use of non_const_base and remove_const?
<main.cpp>
#include<vector >
#include<iostre am>

#include<cctype >
#include"smart_ ptr.h"

using namespace std;
class Base {
public:
Base():ch('*'){
Count++;
}
Base(const Base&):ch('*'){
Count++;
}
virtual char show(){
return ch;
}
virtual ~Base(){Count--;}
virtual void v()const=0;
static unsigned long Count;
private:
char ch;
};
unsigned long Base::Count(0);

/// this will give us lots of derived classes
template<char ch_>
class Derived :public Base {
public:
Derived():ch(ch _){
Count++;
}
Derived(const Derived<ch_>&): ch(ch_){
Count++;
}
virtual char show(){
return ch;
}
virtual ~Derived(){Coun t--;}
virtual void v()const{}
static unsigned long Count;
private:
char ch;

};
template<char ch_>
unsigned long Derived<ch_>::C ount(0);

template<char ch_>
class DerivedSquared :public Derived<ch_{
public:
DerivedSquared( ):ch(std::tolow er(ch_)){
Count++;
}
DerivedSquared( const DerivedSquared< ch_>&):ch(std:: tolower(ch_)){
Count++;
}
virtual char show(){return ch;}
virtual ~DerivedSquared (){Count--;}
virtual void v()const{}
static unsigned long Count;
private:
char ch;

};
template<char ch_>
unsigned long DerivedSquared< ch_>::Count(0);


int main() {

smart_ptr<Deriv ed<'B'>,BuxWrap pedPointertheDP A(new
DerivedSquared< 'B'>);
cout << theDPA->show();

smart_ptr<Base, BuxWrappedPoint ertheDPA2(theDP A);
cout << theDPA2->show();
}

I found that

smart_ptr<inti_ ptr ( new int ( 5 ) );
cout << *i_ptr << '\n';

gives me an error. You should add operator*.

I worked a little on the non-policy based version to have copy_ptr<Basean d
copy_ptr<Derive dbehave as desired. I also added a compile time check
agains using non-polymorphic base classes. This might be overkill.
(Alternatively, one could think about adding a deleter-function that would
use the right destructor in any case.)
#include <algorithm// std::swap

template < typename T >
struct non_polymorphic _class_error {
enum {
trigger = sizeof( dynamic_cast<vo id*>( static_cast<T*> (0) ) )
};

};
// The clone function:
// =============== ====
template < typename T >
void * clone ( void * ptr ) {
return ( ptr == 0 ? 0
: static_cast<voi d*>
( new T ( *( static_cast<T*> ( ptr ) ) ) ) );
}

// The copy_ptr:
// =============

template < typename T >
class copy_ptr {

friend void swap ( copy_ptr<T& p, copy_ptr<T& q ) {
std::swap( p.raw_ptr, q.raw_ptr );
std::swap( p.clone_fct, q.clone_fct );
}

template < typename D >
friend class copy_ptr;

/*
The idea is that in addition to a pointer, we also need
a pointer to the _appropriate_ clone function.
*/
T * raw_ptr;
void * ( *clone_fct ) ( void * );

public:

copy_ptr ( T * ptr = 0)
: raw_ptr ( ptr )
, clone_fct ( clone<T)
{}

template < typename D >
copy_ptr ( D * ptr )
: raw_ptr ( ptr )
, clone_fct ( clone<D)
{
non_polymorphic _class_error<Td 2;
}

// copy construction clones:
copy_ptr ( copy_ptr const & other )
: raw_ptr ( static_cast<T*> ( other.clone_fct ( other.raw_ptr ) ) )
, clone_fct ( other.clone_fct )
{}

template < typename D >
copy_ptr ( copy_ptr<Dconst & other )
: raw_ptr ( static_cast<D*> ( other.clone_fct ( other.raw_ptr ) ) )
, clone_fct ( other.clone_fct )
{
non_polymorphic _class_error<Td 2;
}

// destruction frees the pointee
~copy_ptr ( void ) {
delete ( raw_ptr );
}

// assignment reduces to copy construction
// (for correctness and exception safety):
copy_ptr & operator= ( copy_ptr const & other ) {
copy_ptr dummy ( other );
swap( *this, dummy );
return( *this );
}

template < typename D >
copy_ptr & operator= ( copy_ptr<Dconst & other ) {
copy_ptr dummy ( other );
swap( *this, dummy );
return( *this );
}

T const * operator-( void ) const {
return( raw_ptr );
}

T * operator-( void ) {
return( raw_ptr );
}

T const & operator* ( void ) const {
return( *( this->operator->() ) );
}

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

}; // copy_ptr<T>

Please, let me know what you think.

Have been looking through your code and used this main.cpp

#include<iostre am>

#include<cctype >
#include"copy_p tr.h"

using namespace std;
class Base {
public:
Base():ch('*'){
Count++;
}
Base(const Base&):ch('*'){
Count++;
}
virtual char show(){
return ch;
}
virtual ~Base(){Count--;}
virtual void v()const=0;
static unsigned long Count;
private:
char ch;
};
unsigned long Base::Count(0);

/// this will give us lots of derived classes
template<char ch_>
class Derived :public Base {
public:
Derived():ch(ch _){
Count++;
}
Derived(const Derived<ch_>&): ch(ch_){
Count++;
}
virtual char show(){
return ch;
}
virtual ~Derived(){Coun t--;}
virtual void v()const{}
static unsigned long Count;
private:
char ch;

};
template<char ch_>
unsigned long Derived<ch_>::C ount(0);

template<char ch_>
class DerivedSquared :public Derived<ch_{
public:
DerivedSquared( ):ch(std::tolow er(ch_)){
Count++;
}
DerivedSquared( const DerivedSquared< ch_>&):ch(std:: tolower(ch_)){
Count++;
}
virtual char show(){return ch;}
virtual ~DerivedSquared (){Count--;}
virtual void v()const{}
static unsigned long Count;
private:
char ch;

};
template<char ch_>
unsigned long DerivedSquared< ch_>::Count(0);


int main() {
char ch;

copy_ptr<Derive d<'B' theDPA(new DerivedSquared< 'B'>);
cout << theDPA->show();

copy_ptr<Baseth eDPA2(theDPA);
cout << theDPA2->show();

cout << (*theDPA).show( );
cout << (*theDPA2).show ();

copy_ptr<const BasetheConstPtr (theDPA2);
cin >>ch;
}
I get an error with

copy_ptr<const BasetheConstPtr (theDPA2);

the error (in msvc) is

error C2682: cannot use 'dynamic_cast' to convert from 'const Base *'
to 'void *'

This may not be an issue for deep copy like I said previously, so I am
not sure if it is you requirement.

Just some other comments. As a personal preference, since there are two
main conponents to this class, the outwardly facing
part where on the BaseClass is involved and the internal part where
both BaseClass & DerivedClass are coming into play, to
break these apart , hence my policy.

If you decide to add the ability for const can you send me the code ?

Thnx
N

Nov 12 '06 #5
Posts are getting too long. Let's separate issues.

Ni*****@yahoo.c o.uk wrote:
>template < typename T >
struct non_polymorphic _class_error {
enum {
trigger = sizeof( dynamic_cast<vo id*>( static_cast<T*> (0) ) )
};

};

I forbid myslef from using dynamic_cast, but I would have to try to
remeber the reasons why. But I do have a question.
Isn't it true that dynamic_cast happens at runtime and therefore we
have a overhead, whereas static_cast takes place at compile time, so
we don't. I think the boost is_base combined with boost enable_if lets
us 'error check' at compile time.
If you use

non_polymorphic _class_error< Base dummy;

then there is a dummy variable that is never used. The compiler will
optimize that away. The dynamic_cast, however, will not be evaluated since
it sits within a sizeof expression. Those are not evaluated, instead the
compiler figures out the correct value magically.

Maybe the best way to check is just to put the line

sizeof( dynamic_cast<vo id*>( static_cast<Bas e*>(0) ) );

somewhere. It evaluates to a const-expression without side-effects and
therefore should not create any code.
Best

Kai-Uwe Bux
Nov 12 '06 #6

Kai-Uwe Bux wrote:
Posts are getting too long. Let's separate issues.

Ni*****@yahoo.c o.uk wrote:
template < typename T >
struct non_polymorphic _class_error {
enum {
trigger = sizeof( dynamic_cast<vo id*>( static_cast<T*> (0) ) )
};

};
I forbid myslef from using dynamic_cast, but I would have to try to
remeber the reasons why. But I do have a question.
Isn't it true that dynamic_cast happens at runtime and therefore we
have a overhead, whereas static_cast takes place at compile time, so
we don't. I think the boost is_base combined with boost enable_if lets
us 'error check' at compile time.

If you use

non_polymorphic _class_error< Base dummy;

then there is a dummy variable that is never used. The compiler will
optimize that away. The dynamic_cast, however, will not be evaluated since
it sits within a sizeof expression. Those are not evaluated, instead the
compiler figures out the correct value magically.

Maybe the best way to check is just to put the line

sizeof( dynamic_cast<vo id*>( static_cast<Bas e*>(0) ) );

somewhere. It evaluates to a const-expression without side-effects and
therefore should not create any code.
I am not sure how it can do this, isn't dynamic_cast a runtime
evaluation ?
>

Best

Kai-Uwe Bux
Nov 14 '06 #7

Gianni Mariani wrote:
Ni*****@yahoo.c o.uk wrote:
A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.
I need help with checking that it was exception safe and exception
neutral/
I got a reply from Bux with his code for a smart pointer with far fewer
lines of code
and more cleaner design, not over engineered like mine.

http://groups.google.co.uk/group/com...e5c18bc6bb5c7e
However there was one possible extension to that code :

'The trade-off is that copy_ptr<Basean d copy_ptr<Derive dare
unrelated '
Kai-Uwe Bux
I think I have managed to implement this extension, so I post my code
here along with a main.cpp that exhibists the extension.

Why do you need such a beast ? i.e. what are the requirements and use case ?
I DID know, I am trying to remember why I needed this, after a while it
just became a curious exercise.
>

Any comments about my abuse of the language would be more than welcome

It's kind of hard to read.
Nov 14 '06 #8

Ni*****@yahoo.c o.uk wrote:
A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.
Just as well given that there is no such thing as a virtual
constructor.

class A
{
public:
virtual A( const A & ); // illegal. Constructors can't be virtual
};

< rest snipped >

Nov 14 '06 #9

Earl Purple wrote:
Ni*****@yahoo.c o.uk wrote:
A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.

Just as well given that there is no such thing as a virtual
constructor.

class A
{
public:
virtual A( const A & ); // illegal. Constructors can't be virtual
};
NO what I meant by a virtual copy constructor is something like this

virtual Base * copy()const=0;

and then implemented in derived classes like this
Derived * copy()const{ret urn new Derived(*this); }

http://www.parashift.com/c++-faq-lit....html#faq-20.8

Nov 14 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

42
5820
by: Edward Diener | last post by:
Coming from the C++ world I can not understand the reason why copy constructors are not used in the .NET framework. A copy constructor creates an object from a copy of another object of the same kind. It sounds simple but evidently .NET has difficulty with this concept for some reason. I do understand that .NET objects are created on the GC heap but that doesn't mean that they couldn't be copied from another object of the same kind when...
9
9923
by: Gunnar G | last post by:
Is there anything like vector in STL, that performes deep copy of the elements it contains? I hope this will appear in future releases of STL :)
5
3292
by: Tony Johansson | last post by:
Hello! I'm reading in a book about C++ and that is something that sound strange. It says "Pointers have reference-assignment semantics similar to those in Java. For example, after the assignment Student* john = michael; both john and michael share the same object. This type of an assignment is different then value-assignmnet semantics used by class variables, as in
17
3581
by: baibaichen | last post by:
i have written some code to verify how to disable slicing copy according C++ Gotchas item 30 the follow is my class hierarchy, and note that B is abstract class!! class B { public: explicit B(INT32 i =0):i_(i){} virtual ~B(){}
13
5030
by: blangela | last post by:
I have decided (see earlier post) to paste my Word doc here so that it will be simpler for people to provide feedback (by directly inserting their comments in the post). I will post it in 3 parts to make it more manageable. Below is a draft of a document that I plan to give to my introductory C++ class. Please note that I have purposely left out any mention of safety issues in the ctors which could be resolved thru some combination...
3
3915
by: jacek.dziedzic | last post by:
Hello! Suppose I have a class base, with virtual methods and a virtual destructor and a bunch of classes, derived1, derived2, ... which publicly derive from base. I then have a pointer base* foo; which a complicated code allocates as one of derived's and sets up.
13
3984
by: JD | last post by:
Hi, My associate has written a copy constructor for a class. Now I need to add an operator = to the class. Is there a way to do it without change her code (copy constructor) at all? Your help is much appreciated. JD
1
2114
by: mosfet | last post by:
Hi, I am trying to modify existing code to use smart pointers and I get some issues with virtual methods : class Folder : public Object { public: friend class PimItemCollection; friend class ContactCollection;
50
4532
by: Juha Nieminen | last post by:
I asked a long time ago in this group how to make a smart pointer which works with incomplete types. I got this answer (only relevant parts included): //------------------------------------------------------------------ template<typename Data_t> class SmartPointer { Data_t* data; void(*deleterFunc)(Data_t*);
0
9895
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
11011
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10666
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10724
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9503
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7899
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5929
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4546
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3178
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.