String operations in member initialisation list

S

Samuele Armondi

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::eek:stream& operator << (std::eek:stream&, 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::BasicException
{
private:
std::string tmp;
public:
InvalidCommand(std::string s) : tmp((std::string("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
 
?

=?iso-8859-1?Q?Juli=E1n?= Albo

Samuele Armondi escribió:
class InvalidCommand : public Exceptions::BasicException
{
private:
std::string tmp;
public:
InvalidCommand(std::string s) : tmp((std::string("The command ") + s +
std::string(" is invalid."))), BasicException(tmp, 3) {};
};

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.
 
V

Victor Bazarov

Samuele Armondi said:
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::eek:stream& operator << (std::eek:stream&, 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::BasicException
{
private:
std::string tmp;
public:
InvalidCommand(std::string s) : tmp((std::string("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?


For you, the only way to do it right is

InvalidCommand(const std::string& s) :
BasicException(std::string("The 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
 
S

Samuele Armondi

Victor Bazarov said:
it?


For you, the only way to do it right is

InvalidCommand(const std::string& s) :
BasicException(std::string("The 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
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::BasicException
{
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
 
V

Victor Bazarov

Samuele Armondi said:
errors
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::BasicException
{
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?

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

Victor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top