/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Styrring af objekt allokering ?
Fra : Bo Lorentsen


Dato : 15-12-01 11:25

Hello ...

Jeg ved at der er steder hvor dette er nævnt, men jeg kan ikke lige
komme på hvor, så jeg håber i kan tilgive mig

Hvordan sørger jeg for at et C++ objekt kun kan skabes via "new" (free
store eller indirkte) eller kun automatisk ? Jeg ved godt at der ikke er
officiel understøttelse af dette i sproget selv, men jeg er overbevist om
at der er en uautoriceret måde at styrre dette på.

Årsagen til dette er at jeg fks. gerne vil kunne styrre at en klasse der
skal kunne håndteres via ref. counting, skal jeg sikre mig ikke er allokeret
via staken, da det kun vil give mærkelige seg. faults mfl.

Et hint eller en god henvisning vil jeg værdsætte !

/BL

 
 
Christian Hemmingsen (15-12-2001)
Kommentar
Fra : Christian Hemmingsen


Dato : 15-12-01 18:57

Bo Lorentsen <bl@no.LUE.DK.spam> writes:

> Jeg ved at der er steder hvor dette er nævnt, men jeg kan ikke lige
> komme på hvor, så jeg håber i kan tilgive mig
>
> Hvordan sørger jeg for at et C++ objekt kun kan skabes via "new" (free
> store eller indirkte) eller kun automatisk ? Jeg ved godt at der ikke er
> officiel understøttelse af dette i sproget selv, men jeg er overbevist om
> at der er en uautoriceret måde at styrre dette på.
>
> Årsagen til dette er at jeg fks. gerne vil kunne styrre at en klasse der
> skal kunne håndteres via ref. counting, skal jeg sikre mig ikke er allokeret
> via staken, da det kun vil give mærkelige seg. faults mfl.
>
> Et hint eller en god henvisning vil jeg værdsætte !

Lad være at lave en offentlig contructor, men brug en eller felre
statiske metoder i klassen til at lave dine objekter med.

--
Christian Hemmingsen

Bo Lorentsen (16-12-2001)
Kommentar
Fra : Bo Lorentsen


Dato : 16-12-01 14:20

In <m2d71g8izh.fsf@kewl.kampsax.dtu.dk>, Christian Hemmingsen wrote:

> Lad være at lave en offentlig contructor, men brug en eller felre
> statiske metoder i klassen til at lave dine objekter med.
Jeg kan se Mogens Hansen har givet en meget detailieret beskrivelse
af dette, men det er ellers lige det jeg skal bruge, tak.

/BL

Mogens Hansen (15-12-2001)
Kommentar
Fra : Mogens Hansen


Dato : 15-12-01 21:00


"Bo Lorentsen" <bl@no.LUE.DK.spam> wrote in message
news:sf8fv9.0iq.ln@eth1.lue.dk...
>
> Hvordan sørger jeg for at et C++ objekt kun kan skabes via "new" (free
> store eller indirkte) eller kun automatisk ? Jeg ved godt at der ikke er
> officiel understøttelse af dette i sproget selv, men jeg er overbevist om
> at der er en uautoriceret måde at styrre dette på.
>

Så vidt jeg husker Scott Meyers har en beskriver af dette i en af bøgerne
"Effective C++" og "More Effective C++".

Kun automatisk (og statisk):
gør "operator new" (og eventuelt "operator delete") i de forskellige
varianter private eller protected.

Kun heap:
gør destructor private eller protected.
Lav en statisk funktion til at nedlægge, eller gør klassen friend med
std::auto_ptr<T>:
Der findes kun een destructor - der kan være mange constructorer.

#include <memory>

class heap_only
{
public:
heap_only(void);

private: // or protected
~heap_only();
friend std::auto_ptr<heap_only>;
};

int main(void)
{
heap_only ho1; // error: destructor not accessible
std::auto_ptr<heap_only> ho2(new heap_only());
}

> Årsagen til dette er at jeg fks. gerne vil kunne styrre at en klasse der
> skal kunne håndteres via ref. counting, skal jeg sikre mig ikke er
allokeret
> via staken, da det kun vil give mærkelige seg. faults mfl.
>

Lad en handle-klasse eje det egentlige objekt, og lad handle-klassen
foretage ref.counting og forwarde alle funktioner.
Der er ikke noget run-time overhead, og man fjerner muligheden for at
brugeren af klassen glemmer at håndtere ref.counting rigtigt.

class foo
{
public:
foo(void);
foo(const foo& source);
~foo();
foo& operator=(const foo& lhs);

void func(void);

class impl
{
public:
void func(void);

private:
impl(void);
~impl();
impl(const impl&); // not implemented
impl& operator=(const impl&); // not implemented

friend foo;
unsigned ref_count;
};

private:
impl* impl_;
};


inline foo::foo(void) :
impl_(new impl())
{
}

inline foo::foo(const foo& source) :
impl_(source.impl_)
{
++impl_->ref_count;
}

inline foo:foo()
{
if(!--impl_->ref_count) delete impl_;
}

inline foo& foo:erator=(const foo& rhs)
{
++rhs.impl_->ref_count;
if(!--impl_->ref_count) delete impl_;
impl_ = rhs.impl_;

return *this;
}

void inline foo::func(void)
{
impl_->func();
}

inline foo::impl::impl(void) :
ref_count(1)
{
}

inline foo::impl:impl()
{
}

inline void foo::impl::func(void)
{
// do something
}

int main(void)
{
foo ho1;
foo ho2;
foo ho3(ho2);

ho1 = ho2;
ho3 = ho2;
}


Venlig hilsen

Mogens Hansen



Bo Lorentsen (16-12-2001)
Kommentar
Fra : Bo Lorentsen


Dato : 16-12-01 14:32

In <9vg9u2$t2n$1@news.cybercity.dk>, Mogens Hansen wrote:

> Så vidt jeg husker Scott Meyers har en beskriver af dette i en af
> bøgerne "Effective C++" og "More Effective C++".
Hmm, jeg må se at få fat i dem igen, jeg har ikke haft tiden til at få dem
ordeligt læst, og nu kommer staffen

> Kun automatisk (og statisk):
> gør "operator new" (og eventuelt "operator delete") i de forskellige
> varianter private eller protected.
Tak, men jeg er ikke sikker på jeg forstår hvorfor. Er der nævnt noget om
det i standarten ? Man bruger jo ikke new eller delete til at oprette et
automatisk objekt, eller gør man ?

> Kun heap:
> gør destructor private eller protected. Lav en statisk funktion til at
> nedlægge, eller gør klassen friend med std::auto_ptr<T>: Der findes kun
> een destructor - der kan være mange constructorer.
Se, det var primært denne her der var interessant for mig, og jeg havde
hørt dette før, men det skulle lige opfriskes.
Hvis man ikke gør classen "friend" med "auto_ptr", eller en anden "handler" vil
man så ikke kunne delete objektet ?

> #include <memory>
>
> class heap_only
> {
> public:
> heap_only(void);
>
> private: // or protected
> ~heap_only();
> friend std::auto_ptr<heap_only>;
> };
>
> int main(void)
> {
> heap_only ho1; // error: destructor not accessible
> std::auto_ptr<heap_only> ho2(new heap_only());
> }
Meget smukt, lige hvad jeg skal bruge ... kode eks. Det taler jo på mange
måder et meget tydeligt sprog

> Lad en handle-klasse eje det egentlige objekt, og lad handle-klassen
> foretage ref.counting og forwarde alle funktioner. Der er ikke noget
> run-time overhead, og man fjerner muligheden for at brugeren af klassen
> glemmer at håndtere ref.counting rigtigt.
Deligation er jo en stærk ting, man bliver af og til lidt bange for prisen
(runtime overhead), men min erfaring er at det ofte komme mange fold
igen, ved færre fejl ved det at man skjuler komplexitet

Tak for de gode detalier, jeg vil med fornyet inspiration kaste mig over
min refcounter igen

/BL

Mogens Hansen (16-12-2001)
Kommentar
Fra : Mogens Hansen


Dato : 16-12-01 22:22


"Bo Lorentsen" <bl@no.LUE.DK.spam> wrote in message
> In <9vg9u2$t2n$1@news.cybercity.dk>, Mogens Hansen wrote:

>
> > Kun automatisk (og statisk):
> > gør "operator new" (og eventuelt "operator delete") i de forskellige
> > varianter private eller protected.
> Tak, men jeg er ikke sikker på jeg forstår hvorfor. Er der nævnt noget om
> det i standarten ? Man bruger jo ikke new eller delete til at oprette et
> automatisk objekt, eller gør man ?

Nej - netop.
Ved at gøre "operator new" private eller protected, er de ikke tilgængelige.
Derfor kan man ikke oprette objekter af den type på heapen.
Ved at have constructor og destructor tilgængelig kan de oprettes automatisk
(på stakken) og statisk (global - cirka).

>
> > Kun heap:
> > gør destructor private eller protected. Lav en statisk funktion til at
> > nedlægge, eller gør klassen friend med std::auto_ptr<T>: Der findes kun
> > een destructor - der kan være mange constructorer.
> Se, det var primært denne her der var interessant for mig, og jeg havde
> hørt dette før, men det skulle lige opfriskes.
> Hvis man ikke gør classen "friend" med "auto_ptr", eller en anden
"handler" vil
> man så ikke kunne delete objektet ?

Jo, du kan bare har den statisk funktion til at gøre det med (ikke
compileret):

class foo
{
// ...
static void destroy(foo* object)
{ delete object; }
// ...
private:
~foo();
};

void bar(void)
{
foo* f = new foo;
// ...
foo::destroy(f);
}

> Deligation er jo en stærk ting, man bliver af og til lidt bange for prisen
> (runtime overhead), men min erfaring er at det ofte komme mange fold
> igen, ved færre fejl ved det at man skjuler komplexitet

Hvis man er bange for runtime overhead, så mål det og se om det er et
problem.
Kig på hvordan compileren lægger koden ud.
I eksemplet er der absolut _intet_ runtime overhead, hvis man har en bare
middelmådig compiler.

Venlig hilsen

Mogens Hansen



Bo Lorentsen (17-12-2001)
Kommentar
Fra : Bo Lorentsen


Dato : 17-12-01 21:18

In <9vj32d$25dr$1@news.cybercity.dk>, Mogens Hansen wrote:


> Nej - netop.
> Ved at gøre "operator new" private eller protected, er de ikke
> tilgængelige. Derfor kan man ikke oprette objekter af den type på
> heapen. Ved at have constructor og destructor tilgængelig kan de
> oprettes automatisk (på stakken) og statisk (global - cirka).
Ja, det lyder utroligt logisk nu hvor du nævner det

> Jo, du kan bare har den statisk funktion til at gøre det med (ikke
> compileret):
Ok, den meget ligefrem løsning, men jeg skulle blot proe en protected
descructor, hvorefter mine problemer var løst.

> Hvis man er bange for runtime overhead, så mål det og se om det er et
> problem.
> Kig på hvordan compileren lægger koden ud. I eksemplet er der absolut
> _intet_ runtime overhead, hvis man har en bare middelmådig compiler.
Du har ret, men man bliver en parnoidt fjols af at havde rodet med
embedded systemer

/BL

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste