469,332 Members | 6,612 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,332 developers. It's quick & easy.

Constructor return value?

OK I know a constructor can't have a return value but is it feasible such that I have a class whereby
//in MyClass1.
class MyClass

MyClass1(){}
~MyClass1(){}
MyClass1(int & Result) {Result = InitMyClass()}

int InitMyClass()
//in main.cp

int main(

int result
MyClass theobject(result)
printf("The result of initializing the class is %d", result)
Nov 17 '05 #1
7 6640
Bonj wrote:
OK I know a constructor can't have a return value but is it feasible
such that I have a class whereby: //in MyClass1.h
class MyClass1
{
MyClass1(){};
~MyClass1(){};
MyClass1(int & Result) {Result = InitMyClass()};

int InitMyClass();
}

//in main.cpp

int main()
{
int result;
MyClass theobject(result);
printf("The result of initializing the class is %d", result);
}


Of course it's feasible, and perfectly legal.

The Standard C++ way of indicating failure in a constructor is to throw an
exception, but there might be reasons sometimes that you don't want to do
that (the only one that comes to mind is a severe performance constraint -
exception throwing is expensive).

-cd
Nov 17 '05 #2
There is another reason not to throw out of a constructor: you don't know
how well or badly the object is constructed, so you can't clean up. This is
most important if the constructor allocates resources (e.g. memory)
dynamically.

e.g.

struct C
{
bool *b1, b2;
C() { b1 = b(); b2 = b();}
bool *b() { if (rand() < 0.5) throw true; else return new b; }
};

int main()
{
C* c;
try
{
c = new C();
}
catch (...)
{
// now, what might c point to? What might c->b1 or c->b2 point to?
}
return;
}

"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:%2******************@TK2MSFTNGP10.phx.gbl...
Bonj wrote:
OK I know a constructor can't have a return value but is it feasible
such that I have a class whereby: //in MyClass1.h
class MyClass1
{
MyClass1(){};
~MyClass1(){};
MyClass1(int & Result) {Result = InitMyClass()};

int InitMyClass();
}

//in main.cpp

int main()
{
int result;
MyClass theobject(result);
printf("The result of initializing the class is %d", result);
}


Of course it's feasible, and perfectly legal.

The Standard C++ way of indicating failure in a constructor is to throw an
exception, but there might be reasons sometimes that you don't want to do
that (the only one that comes to mind is a severe performance constraint -
exception throwing is expensive).

-cd

Nov 17 '05 #3
This situation should be handled by following the RAII principle: Resource
Acquisition Is Initialization.

struct C
{
boost::scoped_ptr<bool> b1, b2;
C() : b1(b()), b2(b()) {}
bool *b() { if (rand() < 0.5) throw true; else return new b; }
};

Now if an exception is thrown you're guaranteed that if b1 was initialized,
it'll be destructed.

-cd

Simon Trew wrote:
There is another reason not to throw out of a constructor: you don't
know how well or badly the object is constructed, so you can't clean
up. This is most important if the constructor allocates resources
(e.g. memory) dynamically.

e.g.

struct C
{
bool *b1, b2;
C() { b1 = b(); b2 = b();}
bool *b() { if (rand() < 0.5) throw true; else return new b; }
};

int main()
{
C* c;
try
{
c = new C();
}
catch (...)
{
// now, what might c point to? What might c->b1 or c->b2
point to? }
return;
}

"Carl Daniel [VC++ MVP]"
<cp*****************************@mvps.org.nospam > wrote in message
news:%2******************@TK2MSFTNGP10.phx.gbl...
Bonj wrote:
OK I know a constructor can't have a return value but is it feasible
such that I have a class whereby: //in MyClass1.h
class MyClass1
{
MyClass1(){};
~MyClass1(){};
MyClass1(int & Result) {Result = InitMyClass()};

int InitMyClass();
}

//in main.cpp

int main()
{
int result;
MyClass theobject(result);
printf("The result of initializing the class is %d", result);
}


Of course it's feasible, and perfectly legal.

The Standard C++ way of indicating failure in a constructor is to
throw an exception, but there might be reasons sometimes that you
don't want to do that (the only one that comes to mind is a severe
performance constraint - exception throwing is expensive).

-cd

Nov 17 '05 #4
Absolutely, but (unless I am thinking fuzzily as usual) that only moves it
down a peg: we can only construct members that themselves obey the RAII
principle. (If boost::scoped_ptr's constructor threw after allocating some
resource then we'd be back to square one.)

S.

"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:Oz***************@TK2MSFTNGP12.phx.gbl...
This situation should be handled by following the RAII principle: Resource Acquisition Is Initialization.

struct C
{
boost::scoped_ptr<bool> b1, b2;
C() : b1(b()), b2(b()) {}
bool *b() { if (rand() < 0.5) throw true; else return new b; }
};

Now if an exception is thrown you're guaranteed that if b1 was initialized, it'll be destructed.

-cd

Simon Trew wrote:
There is another reason not to throw out of a constructor: you don't
know how well or badly the object is constructed, so you can't clean
up. This is most important if the constructor allocates resources
(e.g. memory) dynamically.

e.g.

struct C
{
bool *b1, b2;
C() { b1 = b(); b2 = b();}
bool *b() { if (rand() < 0.5) throw true; else return new b; }
};

int main()
{
C* c;
try
{
c = new C();
}
catch (...)
{
// now, what might c point to? What might c->b1 or c->b2
point to? }
return;
}

"Carl Daniel [VC++ MVP]"
<cp*****************************@mvps.org.nospam > wrote in message
news:%2******************@TK2MSFTNGP10.phx.gbl...
Bonj wrote:
OK I know a constructor can't have a return value but is it feasible
such that I have a class whereby: //in MyClass1.h
class MyClass1
{
MyClass1(){};
~MyClass1(){};
MyClass1(int & Result) {Result = InitMyClass()};

int InitMyClass();
}

//in main.cpp

int main()
{
int result;
MyClass theobject(result);
printf("The result of initializing the class is %d", result);
}

Of course it's feasible, and perfectly legal.

The Standard C++ way of indicating failure in a constructor is to
throw an exception, but there might be reasons sometimes that you
don't want to do that (the only one that comes to mind is a severe
performance constraint - exception throwing is expensive).

-cd


Nov 17 '05 #5
Simon Trew wrote:
Absolutely, but (unless I am thinking fuzzily as usual) that only
moves it down a peg: we can only construct members that themselves
obey the RAII principle. (If boost::scoped_ptr's constructor threw
after allocating some resource then we'd be back to square one.)


Sure. But properly designed RAII containers (like boost::scoped_ptr) will
behave correctly. In the example given, the only thing that can throw is
the new expression, and if that throws boost::scoped_ptr's constructor will
never be entered. If new doesn't throw and scoped_ptr's constructor is
entered, it must either properly recover from any exception or (in reality)
promise not to throw.

-cd
Nov 17 '05 #6
Simon Trew wrote:
Absolutely, but (unless I am thinking fuzzily as usual) that only moves it
down a peg: we can only construct members that themselves obey the RAII
principle.
Well, yes, you gotta start somewhere. :) But once you have a set of nice,
exception-safe, low-level classes such as std::string, std::vector, various
smart pointers, etc, you can build your own classes in terms of them and not
worry about them leaking.
(If boost::scoped_ptr's constructor threw after allocating some
resource then we'd be back to square one.)


That's a problem only if you have a mix of exception-safe and unsafe
members. I can't remember the last time I used a raw pointer as a class
member, and that pointer owned the data it pointed to.

--
Doug Harrison
Microsoft MVP - Visual C++
Nov 17 '05 #7
Yep, I was not suggesting that boost::scoped_ptr behaved anything other than
properly.

"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:%2****************@TK2MSFTNGP09.phx.gbl...
Sure. But properly designed RAII containers (like boost::scoped_ptr) will
behave correctly.

Nov 17 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by Michael Klatt | last post: by
8 posts views Thread by Nils O. Selåsdal | last post: by
3 posts views Thread by tshad | last post: by
3 posts views Thread by Neelesh Bodas | last post: by
20 posts views Thread by lovecreatesbeauty | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
reply views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.