return value of constructor

Started by
29 comments, last by Conner McCloud 18 years, 1 month ago
Quote:Original post by Bregma
The answer is that functions can return values. Constructors and destructors are not functions. They cannot return values. It's just unfortunate that their definitions use a syntax apparently similar to that of functions. Don't confuse syntax with semantics.


I can think of only three ways they differ from functions:
1) No return type
2) Initializer lists
3) The user isn't supposed to normally call them directly

(3) doesn't make much of an argument, because it's just like saying "don't call free() twice in a row on the same pointer". (2) is a hack that may or may not justify adding something conceptually different. (1), well, I've already covered that.

In fact, from the C++ FAQ Lite, I see this code:
void someCode() {   char memory[sizeof(Fred)];   void* p = memory;   Fred* f = new(p) Fred();   ...   f->~Fred();   // Explicitly call the destructor for the placed object }
which tells me that at least destructors can be called like functions. Destructors also hang out with other functions in the vtable if you declare them virtual.

They may indeed not be functions, but it seems an even subtler distinction than that between arrays and pointers.

So, you've cleared up a misunderstanding of mine (c/dtors are not functions), but that doesn't change the "heart" of the question. I'll rephrase to, "Why aren't constructors/destructors functions?"
Advertisement
Look at it this way: for a stack allocated object if the constructor were allowed to fail in any way but an exception you could have an invalid object visible in your scope. An exception forces you to leave the current scope, making the object invisible from the next point of execution. Because of this, constructors really can't be allowed to fail to construct the object except in 'exceptional' circumstances, which would then call for an exception. So in case the constructor fails in a non-exceptional way the object must still be in a valid state, even if that state is some kind of dead state.

Java obviously doesn't suffer this, but they probably chose the same behaviour for two reasons: first, C++ programmers are familiar with it and second, if constructors were allowed to fail without an exception you would end up with a null pointer which you probably aren't expecting, which will then cause an exception a few lines later when you use the pointer (and the exception type will be less useful since it will be a NullPointerException rather than whatever the real failure was).
Random fact: constructors are all unnamed. Chew on that for a bit.

CM
Quote:Original post by Conner McCloud
Random fact: constructors are all unnamed. Chew on that for a bit.


Please elaborate.
The return type of calling ClassName() is ClassName. Consequently, you may consider that the return type of the constructor, which is obvious, fixed and thus unnecessary. There is no reason to mandate that you supply information that never, ever varies.

[Edit: ClassName() returns ClassName, not ClassName *. Thanks to oggialli for the catch.]

Before anyone brings it up, int main is necessary because the value must be returned to the operating system, and because before C++ was standardized it was legal to have other return types for main. There is no valid comparison here.

Constructors are not unnamed. Their identifiers are an important part of their signature, especially when you consider that, like all functions in C and C++, they can be overloaded. A more trite counter argument would be the Scope::Identifier syntax for class members indicating that constructors are named ClassName::ClassName.

That is, unless Connor has a different definition of being "unnamed."

[Edited by - Oluseyi on March 15, 2006 6:57:02 PM]
ClassName() doesn't return ClassName*, new ClassName() does. ClassName() returns ClassName.
Olli Salli
Quote:Original post by oggialli
ClassName() doesn't return ClassName*, new ClassName() does. ClassName() returns ClassName.

Good catch. Thanks.
Quote:12.1 Constructors
1 Constructors do not have names. A special declarator syntax using an optional sequence of function specifiers (7.1.2) followed by the constructor’s class name followed by a parameter list is used to declare or define the constructor. In such a declaration, optional parentheses around the constructor class name are ignored.

2 A constructor is used to initialize objects of its class type. Because constructors do not have names, they are never found during name lookup; however an explicit type conversion using the functional notation (5.2.3) will cause a constructor to be called to initialize an object.
Thanks Guys!!But can we reach to some conclusion?
Quote:Original post by TEUTON
Thanks Guys!!But can we reach to some conclusion?


I think the conclusion is that Constructors aren't functions, they just play one on TV. Not being functions, they don't need to follow the rules of functions. I think that not having a return type is just a reminder that we're not in Kansas anymore.

Is there a rationale for not making them functions? Other languages (I know at least Smalltalk and Objective-C) use functions instead of something special. On the other hand, it wouldn't surprise me if there's some interaction among C++'s rules that causes problems with this. (A simple example is that #define's are much worse in C++ than in C because of things like function overloading and C++ namespaces.)

This topic is closed to new replies.

Advertisement