String operations in member initialisation list

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Samuele Armondi

    String operations in member initialisation list

    Hi,
    I'm writing some exception class for a project, and I've got a class called
    BasicException that looks like this:
    class BasicException
    {
    private:
    std::string Description;
    int Number;

    public:
    BasicException( std::string, int);
    friend std::ostream& operator << (std::ostream&, BasicException& );
    };
    where the string and the int in the constructor initialize the description
    and the error number respectively.
    I also have a derived class called InvalidCommand:
    class InvalidCommand : public Exceptions::Bas icException
    {
    private:
    std::string tmp;
    public:
    InvalidCommand( std::string s) : tmp((std::strin g("The command ") + s +
    std::string(" is invalid."))), BasicException( tmp, 3) {};
    };
    the string s is the command name, which is then incorporated into the error
    description. This compiles fine in Dev-Cpp (which I always thought had
    problems handling string types) but it produces a raft of stupid errors in
    VC++ (such as template already defined in <algorithm> and other errors of
    the sort.
    Is it correct to use the string like I'm using it in the constructor of
    InvalidCommand? If it is not, can someone think of another way of doing it?
    Thanks in advance,
    S. Armondi

    --
    To contact me by email, remove _NOSPAM_ from the address.


    --
    To contact me by email, remove _NOSPAM_ from the address.


  • Julián Albo

    #2
    Re: String operations in member initialisation list

    Samuele Armondi escribió:
    [color=blue]
    > class InvalidCommand : public Exceptions::Bas icException
    > {
    > private:
    > std::string tmp;
    > public:
    > InvalidCommand( std::string s) : tmp((std::strin g("The command ") + s +
    > std::string(" is invalid."))), BasicException( tmp, 3) {};
    > };[/color]

    BasicException is constructed before tmp, the order used in the
    initializtion list is ignored (some compilers put a warning). And you
    probably not need it tmp at all.

    Regards.

    Comment

    • Victor Bazarov

      #3
      Re: String operations in member initialisation list

      "Samuele Armondi" <sammyboyuk_NOS PAM_@hotmail.co m> wrote...[color=blue]
      > Hi,
      > I'm writing some exception class for a project, and I've got a class[/color]
      called[color=blue]
      > BasicException that looks like this:
      > class BasicException
      > {
      > private:
      > std::string Description;
      > int Number;
      >
      > public:
      > BasicException( std::string, int);
      > friend std::ostream& operator << (std::ostream&, BasicException& );
      > };
      > where the string and the int in the constructor initialize the description
      > and the error number respectively.
      > I also have a derived class called InvalidCommand:
      > class InvalidCommand : public Exceptions::Bas icException
      > {
      > private:
      > std::string tmp;
      > public:
      > InvalidCommand( std::string s) : tmp((std::strin g("The command ") + s +
      > std::string(" is invalid."))), BasicException( tmp, 3) {};
      > };
      > the string s is the command name, which is then incorporated into the[/color]
      error[color=blue]
      > description. This compiles fine in Dev-Cpp (which I always thought had
      > problems handling string types) but it produces a raft of stupid errors in
      > VC++ (such as template already defined in <algorithm> and other errors of
      > the sort.
      > Is it correct to use the string like I'm using it in the constructor of
      > InvalidCommand? If it is not, can someone think of another way of doing[/color]
      it?


      For you, the only way to do it right is

      InvalidCommand( const std::string& s) :
      BasicException( std::string("Th e command ") + s + " is invalid", 3),
      tmp(std::string ("The command ") + s + " is invalid")
      {
      }

      The base classes are constructed before members, and member are
      constructed in the declaration order. The order in which you
      place them in the initialisation list does NOT matter. You relied
      on the 'tmp' being constructed before the base class. It is not.

      Victor


      Comment

      • Samuele Armondi

        #4
        Re: String operations in member initialisation list


        "Victor Bazarov" <v.Abazarov@att Abi.com> wrote in message
        news:vfjtr4p8ua gd8b@corp.super news.com...[color=blue]
        > "Samuele Armondi" <sammyboyuk_NOS PAM_@hotmail.co m> wrote...[color=green]
        > > Hi,
        > > I'm writing some exception class for a project, and I've got a class[/color]
        > called[color=green]
        > > BasicException that looks like this:
        > > class BasicException
        > > {
        > > private:
        > > std::string Description;
        > > int Number;
        > >
        > > public:
        > > BasicException( std::string, int);
        > > friend std::ostream& operator << (std::ostream&, BasicException& );
        > > };
        > > where the string and the int in the constructor initialize the[/color][/color]
        description[color=blue][color=green]
        > > and the error number respectively.
        > > I also have a derived class called InvalidCommand:
        > > class InvalidCommand : public Exceptions::Bas icException
        > > {
        > > private:
        > > std::string tmp;
        > > public:
        > > InvalidCommand( std::string s) : tmp((std::strin g("The command ") + s +
        > > std::string(" is invalid."))), BasicException( tmp, 3) {};
        > > };
        > > the string s is the command name, which is then incorporated into the[/color]
        > error[color=green]
        > > description. This compiles fine in Dev-Cpp (which I always thought had
        > > problems handling string types) but it produces a raft of stupid errors[/color][/color]
        in[color=blue][color=green]
        > > VC++ (such as template already defined in <algorithm> and other errors[/color][/color]
        of[color=blue][color=green]
        > > the sort.
        > > Is it correct to use the string like I'm using it in the constructor of
        > > InvalidCommand? If it is not, can someone think of another way of doing[/color]
        > it?
        >
        >
        > For you, the only way to do it right is
        >
        > InvalidCommand( const std::string& s) :
        > BasicException( std::string("Th e command ") + s + " is invalid",[/color]
        3),[color=blue]
        > tmp(std::string ("The command ") + s + " is invalid")
        > {
        > }
        >
        > The base classes are constructed before members, and member are
        > constructed in the declaration order. The order in which you
        > place them in the initialisation list does NOT matter. You relied
        > on the 'tmp' being constructed before the base class. It is not.
        >
        > Victor
        >
        >[/color]
        Thanks for the replies. After reading the post by john Harrison (calling
        member funcs from an initialiser list) i tried to following, which compiles
        in VC++:
        class InvalidCommand : public Exceptions::Bas icException
        {
        private:
        std::string& MakeString(std: :string& s)
        {
        s.insert(0, "The command ");
        s.append(" is invalid");
        return s;
        }
        public:
        InvalidCommand( std::string s) : BasicException( MakeString(s), 3) {};
        };
        I gather that since MakeString is not accessing any unitialised class
        members, the code is ok. Am I correct?
        Thanks in advance,
        S. Armondi


        Comment

        • Victor Bazarov

          #5
          Re: String operations in member initialisation list

          "Samuele Armondi" <sammyboyuk_NOS PAM_@hotmail.co m> wrote...[color=blue]
          > "Victor Bazarov" <v.Abazarov@att Abi.com> wrote in message
          > news:vfjtr4p8ua gd8b@corp.super news.com...[color=green]
          > > "Samuele Armondi" <sammyboyuk_NOS PAM_@hotmail.co m> wrote...[color=darkred]
          > > > Hi,
          > > > I'm writing some exception class for a project, and I've got a class[/color]
          > > called[color=darkred]
          > > > BasicException that looks like this:
          > > > class BasicException
          > > > {
          > > > private:
          > > > std::string Description;
          > > > int Number;
          > > >
          > > > public:
          > > > BasicException( std::string, int);
          > > > friend std::ostream& operator << (std::ostream&, BasicException& );
          > > > };
          > > > where the string and the int in the constructor initialize the[/color][/color]
          > description[color=green][color=darkred]
          > > > and the error number respectively.
          > > > I also have a derived class called InvalidCommand:
          > > > class InvalidCommand : public Exceptions::Bas icException
          > > > {
          > > > private:
          > > > std::string tmp;
          > > > public:
          > > > InvalidCommand( std::string s) : tmp((std::strin g("The command ") + s[/color][/color][/color]
          +[color=blue][color=green][color=darkred]
          > > > std::string(" is invalid."))), BasicException( tmp, 3) {};
          > > > };
          > > > the string s is the command name, which is then incorporated into the[/color]
          > > error[color=darkred]
          > > > description. This compiles fine in Dev-Cpp (which I always thought had
          > > > problems handling string types) but it produces a raft of stupid[/color][/color][/color]
          errors[color=blue]
          > in[color=green][color=darkred]
          > > > VC++ (such as template already defined in <algorithm> and other errors[/color][/color]
          > of[color=green][color=darkred]
          > > > the sort.
          > > > Is it correct to use the string like I'm using it in the constructor[/color][/color][/color]
          of[color=blue][color=green][color=darkred]
          > > > InvalidCommand? If it is not, can someone think of another way of[/color][/color][/color]
          doing[color=blue][color=green]
          > > it?
          > >
          > >
          > > For you, the only way to do it right is
          > >
          > > InvalidCommand( const std::string& s) :
          > > BasicException( std::string("Th e command ") + s + " is invalid",[/color]
          > 3),[color=green]
          > > tmp(std::string ("The command ") + s + " is invalid")
          > > {
          > > }
          > >
          > > The base classes are constructed before members, and member are
          > > constructed in the declaration order. The order in which you
          > > place them in the initialisation list does NOT matter. You relied
          > > on the 'tmp' being constructed before the base class. It is not.
          > >
          > > Victor
          > >
          > >[/color]
          > Thanks for the replies. After reading the post by john Harrison (calling
          > member funcs from an initialiser list) i tried to following, which[/color]
          compiles[color=blue]
          > in VC++:
          > class InvalidCommand : public Exceptions::Bas icException
          > {
          > private:
          > std::string& MakeString(std: :string& s)
          > {
          > s.insert(0, "The command ");
          > s.append(" is invalid");
          > return s;
          > }
          > public:
          > InvalidCommand( std::string s) : BasicException( MakeString(s), 3) {};
          > };
          > I gather that since MakeString is not accessing any unitialised class
          > members, the code is ok. Am I correct?[/color]

          Yes. And to be on the safe side, make it 'static' (since you don't
          need anything from any particular object).

          Victor


          Comment

          Working...