Gå til innhold

Medlems-initialisering under konstruksjon


Anbefalte innlegg

Hei der,

Paster kode med forklaring av problemet i kommentarer:

 

#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>

using namespace std;


class A {
public:
       A(int i)
               :_i(i)
       {
               /*
                       Now lets say there is a lot of code here for some reason,
                       this takes time.
               */
       } // constructor


       void operator=(int i)
       {
               _i = i;
               /*
                       Now lets say there is a lot of code here for some reason,
                       this takes time (again).
               */
       } // operator=


       int _i;
}; // A


class B {
public:
       B(int i)
               :_a(i)
       {
       } // constructor


       B(char const* c)
               :_a(0)
       {
               _a = atoi(c);
               /*
                       Ok, this is the problem:
                       I know the atoi()-call could be put in the initializer list,
                       instead of giving _a a default value 0, but there
                       are situations when this is not possible, like
                       in the constructor below:
               */
       } // constructor


       template<typename T>
       B(T const& s)
               :_a(0)
       {
               stringstream ss;
               ss << s;
               int i;
               ss >> i;
               _a = i;
       } // constructor


       A _a;
}; // B


int main ()
{
       B b1(123);
       B b2("321");

       cout << b1._a._i << endl;
       cout << b2._a._i << endl;
       return(0);
} // main

 

Virker kanskje som småplukk(?), men det er snakk om klasser det skal lages masse små objekter av - og det må gå fort! :) Noe jeg misser her, en mulighet jeg overser?

 

Edit:

Rettet teit feil ..

Det går vel å lage en funksjon "utenfor" klassen og kalle den i initialiserings-listen ... men suger litt imho .. (og er det mulig i alle tilfeller?)

Endret av søppel
Lenke til kommentar
Videoannonse
Annonse

Det nærmeste jeg kommer er som du selv nevner å lage en hjelpefunksjon. F.eks:

 

template <typename T>
inline int ToInt(const T & val)
{
   std::stringstream ss;
   ss << val;
   int ret;
   ss >> ret;
   return ret;
}

// ...

class B
{
   //...
   template <typename T>
   B(const T & ref) : m_obj(ToInt(ref))
   {
   }
};

 

Om det er noe særlig raskere enn din første variant er vel heller tvilsomt. Spesielt ikke hvis T er en aritmetisk type (int, short, float..) og ToInt ikke er optimalisert for disse typene.

Lenke til kommentar

Problemet er mer generellt, problemet er at man i mange tilfeller må ha mer kode enn man får plass til i initialiseringslisten -- og at man da først må konstruere medlems-klassen med foreløpige (ikke-nyttige) data, som tar tid:

 

        A(int i)
              :_i(i)
      {
              /*
                      Now lets say there is a lot of code here for some reason,
                      this takes time.
              */
      } // constructor

 

..for så, etterpå, å assigne den egentlige verdien/dataene slik de kommer frem etter å ha gått igjennom den koden som jeg ikke får plass til i initialiseringslisten:

 

       void operator=(int i)
      {
              _i = i;
              /*
                      Now lets say there is a lot of code here for some reason,
                      this takes time (again).
              */
      } // operator=

 

(begge funksjonene tar tid -- så det er her jeg var ute etter å spare tid, altså ved å bare kalle den ene (bare konstruktøren))

 

Så dette med stringstream .. konvertering til int .. var bare ment som et ex. egentlig.

 

Løsningen blir, ser det ut til, å putte ting i en egen (medlems)funksjon, som i test-ex. under:

 

#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>

using namespace std;


class B {
public:
      B(int i)
    :_a(test(i))
      {
      } // constructor

int _a;
int _b;


private:
inline int test(int i)
{
  /* some code here that does not fit in an initializer-list */
 cout << "test" << endl;
 _b = i + 1;
 return(i);
} // test
}; // B


int main ()
{
      B b1(123);

      cout << b1._a << endl;
      cout << b1._b << endl;
      return(0);
} // main

 

(koden har ingen praktisk hensikt akkurat her så klart)

 

Takk for svar, løsningen var (som vanlig?) enklere enn jeg trodde.

Endret av søppel
Lenke til kommentar

Det finnes flere løsninger på dette. En av dem er en medlemsfunksjon, en annen er en hjelpefunksjon á la ToInt() som er mer generell etter min mening. Du kan også flytte funksjonalitet over i A c'toren (i det første eksemplet). Det avhenger av hva man skal gjøre i test funksjonen.

 

Hvis du skal som du viste i den første kodesnutten din; å konvertere en generell type til en int, er en global hjelpefunksjon mer elegant enn en privat medlemsfunksjon etter min mening.

 

For å ta det siste eksemplet ditt, hva med dette:

 

class B
{
   B(int i) : _a(i), _b(i+1)
   {
       cout << "test" << endl;
   }

   //...
};

 

Det jeg mener er at det ikke finnes et generelt svar fordi det finnes mange muligheter som egner seg best i ulike situasjoner.

Lenke til kommentar

Dette er offtopic i forhold til tråd-tittelen, men ..

 

Er så himmla lei Make nå, så vurderer å lage et build-system i Perl. Det må da være det script-språket som er tilgjengelig tilnærmet-lik overalt?

 

Noen kommentarer/idéer?

 

Edit:

..eller kanskje Lisp? .. Bare for gøy liksom? :}

Endret av søppel
Lenke til kommentar

Helt sikkert.

 

Edit:

Altså, basert på det jeg sier, tror du virkelig at ting er slik at de fungerer "out of the box" under et hvilket som helst IDE? F.eks. VC?

 

Jeg snakker om et helt tre med masse programmer, biblioteker, avhengigheter og stasj.

 

Her trykker jeg forresten F5 ..

 

Edit2:

Jeg er sikkert litt dum som "går på denne"; du må ha skjønnt det jeg nevner i første Edit.

Endret av søppel
Lenke til kommentar

hva er det du snakker om nå søppel?

har du gått på syre igjen?

klarer du ikke tanken på at ikke alle gjør ting på akkurat den måten du gjør ting på? hvis du har lyst til å lage makefiler for hvert forpulte prosjekt, eller komme med den geniale ideen om at du skal lage et eget build system i perl, så gjerne for me. jeg for min del er godt fornøyd med at alt funker "out of the box" ved at jeg trykker f7. at du trykker f5 bryr jeg meg heller lite om. i vc bygger du nemlig prosjektene med f7, mens f5 kjører de i debug-mode.

 

dork.

Endret av saboi
Lenke til kommentar

Jam har jeg tittet litt på tidligere, men Scons er nytt for meg. Får gjøre noen nye forsøk - Makefilene her begynner å bli himmla stygge .. derfor jeg må finne noe annet. (rant)Jeg sliter i hvertfall med å rydde opp i dem. Det er kanskje(?) min skyld; altså jeg er vannt til å uttrykke meg v.h.a. et språk som beskriver en prosess "skritt for skritt" .. dette med Make er liksom. .. hm .. "gjør noe slikt hvis du ser filer som er noe slikt". ..ellernoe .. og/eller blandt annet. (/rant)

 

For å komme med noe konkret så sliter jeg med å kompilere programmer "samtidig" som jeg kompilerer biblioteker; http://www.cpp.no/websvn/filedetails.php?r...file&rev=0&sc=1

 

Her kompileres et bibliotek .. include.mak ligger på hjemmesiden, www.cpp.no/oxymora/ .. kan egentlig ikke forvente at noen gidder å sette seg inn i dette. Nettopp fordi det er en Makefile og .. det ikke eksisterer noen "start" og "slutt" (prosess), eller .. det mangler f.eks. mulighet til å lage/kalle funksjoner.

 

(kanskje se om jeg greier å uttrykke meg bedre i morra .. litt seint/tidlig nå)

 

Derfor har jeg egentlig lyst til å gå over til noe helt annet.

 

saboi:

*ignore* ... er jeg ikke flink?

 

Edit:

..heh.. eller få se hva du kompilerer (alt?) "out of the box" da?

Endret av søppel
Lenke til kommentar

Scons er i ferd med å bli ganske så populært, men det forutsetter at du ikke har noe imot Python da :] Det finnes allerede et uoffisielt build-system for Boost.Python som benytter Scons, tror det er en del mindre komplisert enn det eksisterende. Mener også å ha hørt at en stor spillutvikler (id?) holder på å innføre Scons internt.

Lenke til kommentar

Jøsses. Ser ut som du bryter med et par lisenser i oxymora søppel. Det er vel ikke helt lovlig er det vel? Og jeg som trodde at open source horer tok dette som hellig, så feil kan man ta.

/* 
        Copyright (C) 2003 by Lars-Rune Nøstdal.
        See http://oxymora.nostdal.net for details and licenses.
*/


#ifndef _OXYMORA_MATH_SQRT_HH_
#define _OXYMORA_MATH_SQRT_HH_

#include <util/ifthenelse.hh>

namespace Oxymora {
       namespace Math {

               // primary template for main recursive step 
 template<int N, int LO=1, int HI=N> 
               class Sqrt { 
               public: 
                       // compute the midpoint, rounded up 
 	enum { mid = (LO + HI + 1) / 2 }; 
                       
                       // search a not too large value in a halved interval 
 	typedef typename Oxymora::Util::IfThenElse<(N<mid * mid), 
                               Sqrt<N, LO, mid - 1>, 
                               Sqrt<N, mid, HI> >::result
                       SubT; 
                       enum { result = SubT::result }; 
               }; 
               
               // partial specialization for end of recursion criterion 
 template<int N, int S> 
               class Sqrt<N, S, S> { 
               public: 
                       enum { result = S }; 
               }; 


       } // namespace Math
} // namespace Oxymora

#endif // #define _OXYMORA_MATH_SQRT_HH_

 

The following code example is taken from the book
C++ Templates - The Complete Guide
by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
© Copyright David Vandevoorde and Nicolai M. Josuttis 2002


#include "ifthenelse.hpp"

// primary template for main recursive step
template<int N, int LO=1, int HI=N>
class Sqrt {
 public:
   // compute the midpoint, rounded up
   enum { mid = (LO+HI+1)/2 };

   // search a not too large value in a halved interval
   typedef typename IfThenElse<(N<mid*mid),
                               Sqrt<N,LO,mid-1>,
                               Sqrt<N,mid,HI> >::ResultT
           SubT;
   enum { result = SubT::result };
};

// partial specialization for end of recursion criterion
template<int N, int S>
class Sqrt<N, S, S> {
 public:
   enum { result = S };
};

 

These are the examples from the following book:

David Vandevoorde, Nicolai M. Josuttis

C++ Templates - The Complete Guide

Addison-Wesley, 2002

ISBN 0-201-73484-2

 

 

For further informations see: http://www.josuttis.com/tmplbook/

 

We welcome your feedback. The best way to reach us is by Email: [email protected]

 

Copyright 2003 by Pearson Education, Inc., David Vandevoorde, and Nicolai M. Josuttis.

All rights reserved.

 

Permission to use, copy, modify and distribute this software for personal and educational use is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Pearson Education or the authors are not used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Pearson Education and the authors make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.

 

PEARSON EDUCATION AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL PEARSON EDUCATION OR THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

 

samme gjelder med pow.

 

dork.

Endret av saboi
Lenke til kommentar

Eu'kh .. jeg har rapportert deg, saboi ..

 

Edit:

http://www.josuttis.com/tmplbook/copyright.html

"Permission to ... is hereby granted ..." .. etc. hva er problemet?

 

Jeg har også mailet flere rettinger til forfatterene av boka .. så noe av koden er faktisk "fra meg", sånn uansett. Hva sier du til det?

 

Oxymora er heller ikke "sluppet" ennå, og jeg er klar over at jeg ikke har nevnt ©'er her og der .. Dette fikses så klart etterhvert; altså før "release".

 

Edit2:

Tror i grunn jeg samler alt slikt i en COPYRIGHT-fil i rota. Og henviser til den fra alle filene, det må da være greit.

 

..og uansett; er du off-topic.

 

Edit3:

Tar å titter på Scons i kveld, høres spennende ut - Python er sikkert 100 ganger bedre en Makefile-script-"språket" .. :]

 

Edit4:

Svarer på det under: Har rapporter deg til admin/mods her på hw.

Endret av søppel
Lenke til kommentar

haha?

du har rapportert meg?

til hvem og hvorfor?

du spiser for mye syre du.

Og så kommer du med at noe av koden er din så du trenger ikke bruker copyrighten?

 

"Permission to ... is hereby granted ..." .. etc. hva er problemet?

 

eh er du dum eller bare later du som?

 

det står klart og tydelig at du må legge til copyright noticen og den permissionen i fila, noe som du ikke har gjort. I tillegg prøver du å ta æren for den selv ved å skrive din egen copyright på den. Det er problemet.

Endret av saboi
Lenke til kommentar
Dette er offtopic i forhold til tråd-tittelen, men ..

 

Er så himmla lei Make nå, så vurderer å lage et build-system i Perl. Det må da være det script-språket som er tilgjengelig tilnærmet-lik overalt?

 

Noen kommentarer/idéer?

 

Edit:

..eller kanskje Lisp? .. Bare for gøy liksom? :}

Edit2:

Tror i grunn jeg samler alt slikt i en COPYRIGHT-fil i rota. Og henviser til den fra alle filene, det må da være greit.

 

..og uansett; er du off-topic.

 

 

du er virkelig så tjukk i huet som du ser ut som.

Lenke til kommentar
Gjest
Dette emnet er stengt for flere svar.
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...