0

All books and internet pages I read say that C++ constructors do not have a return value and they just initialize an object:

#include <iostream>

class Number {
    int m_val{};

public:
    Number() = default;
    Number(int val) : m_val(val) {}

    int val() { return m_val; }
};

int main() {
    Number n;  // Initializing object with defualt constructor
    std::cout << n.val() << '\n';
    return 0;
}

But it turns out that also I can use constructors for assignment and for calling methods of object, like it returns the value of this object:

Number n = Number(10);                 // This works
std::cout << Number(29).val() << '\n'; // And this

In other similar stackoverflow questions like this and this people write that this semantics creates a value-initialized temporary object of type Number , but it does not answer my question.

So does constructor return object, or maybe it is some c++ entity that i've never heard of?

  • `Number(10)` is not a call to the constructor, it's the creation of an object. Constructor definition and object creation just happen to follow similar syntax, i.e. using the class name in a "function-like" manner (this saves on reserved words, which C++ has always preferred) . Constructors themselves do not have names and can't be referred to in code. – molbdnilo Mar 30 '22 at 12:57
  • "_Value-initialized_" has a specific technical meaning. It is a form of initialization that applies specifically only if there is _no_ argument in the parentheses. So it doesn't apply to your example, nor the second link. – user17732522 Mar 30 '22 at 12:58
  • 3
    It's not really worth to consider constructors in the same way as other functions. It's one of the *special member functions*, and it's special because it doesn't have a name, uses a specificly defined syntax and is called in specific situations. You technically can't call the constructor yourself, it is invoked when object is created. – Yksisarvinen Mar 30 '22 at 12:58
  • 1
    @SoldatovAndrey Since you commented "Thank you" on the answers: Please have a look at [What should I do when someone answers my question?](https://stackoverflow.com/help/someone-answers) – user17732522 Mar 30 '22 at 13:00
  • `Number n = Number(10);` is **not** assignment, despite the `=` sign; it's still initialization. – Pete Becker Mar 30 '22 at 13:41
  • 1
    @Yksisarvinen [Here](https://godbolt.org/z/jdc5hGTP9) I call the constructor directly ;) – Aykhan Hagverdili Mar 30 '22 at 13:49
  • 1
    @AyxanHaqverdili Evil genius but alas not portable. I was thinking if you could could bind `std::function` to a constructor and call it that way. – Bathsheba Mar 30 '22 at 15:08
  • @Bathsheba That's flattering, especially coming from you! I doubt you can get it working with `std::function` since there is no way to take address of the constructor that I know of, other than the `extern "C"` trick. – Aykhan Hagverdili Mar 31 '22 at 07:34

2 Answers2

4

Does C++ constructor return an object?

No, a constructor doesn't return anything. A constructor will be called when an object is created and the implicit this will point to the object that is being constructed.


P.S.

But it turns out that also I can use constructors for assignment and for calling methods of object, like it returns the value of this object:

Number n = Number(10);  

That's not an assignment. That syntax of copy-initialisation.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • *That's not an assignment. That syntax of copy-initialisation.* `n = Number(10)` but this is an assignment, so rather missed point as for op's interest about the ctor call syntax. – bloody Mar 30 '22 at 13:19
  • 1
    @bloody That is an assignment, yes. The answer to OP's question is no. I don't see how that misses the point. – eerorika Mar 30 '22 at 13:20
  • I assume op doesn't care about strict nomenclature but the ctor call syntax in assignments/initializations vs return value mechanism. – bloody Mar 30 '22 at 13:30
  • 1
    @bloody `I assume op doesn't care about strict nomenclature` If that's the case, then now is a good time to start caring. `but the ctor call syntax` There is no syntax to call a constructor in C++. There are various ways of creating objects, and the language always calls the constructor for you. – eerorika Mar 30 '22 at 13:39
  • @eerorika: Placement new does, almost. I know what you mean though. You *can* call a destructor explicitly of course. I wonder if some `~~C()` notation could be used to call a constructor in future standards? – Bathsheba Mar 30 '22 at 14:41
  • *There is no syntax to call a constructor in C++* . Everyone I know in the industry calls invoking a constructor() 'calling a constructor'. Otherwise there are no function calls either, language calls them for you. Note that ppl often discuss visible code structure for clear reference among them and communication. In that context yes - there is a constructor call. First time I can hear this term is reserved for some language internal snobbery. And certainly such revelations don't help ppl solve their problems on SO. – bloody Mar 30 '22 at 23:40
  • @bloody Object creation does more than just calling the constructor. If the object is on the stack, it allocates memory of appropriate size and alignment, and then calls the constructor. If it's a member variable, simply passes in the already-allocated memory, etc. It's not helpful to anyone to lump all that magic into calling it a "function call". It's nice when words mean something. – Aykhan Hagverdili Mar 31 '22 at 08:07
  • *"There is no syntax to call a constructor in C++"* When you "call" a constructor of a base class (or an overloaded constructor of the same class) on the initialization list it is NOT an object creation (just part of that process) and a literal counter-example of your "oracle": a call but not an allocation. The rest about helpfulness and words meaning I won't even comment since what are they worth if they are simply wrong. – bloody Mar 31 '22 at 09:23
0

Indeed a constructor doesn't have a return value.

But Number(10) is an object of type Number. And that is an expression with a value.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 3
    Isn't it more accurate (at least since C++17) to call `Number(10)` a prvalue expression? No temporary is created in `Number n = Number(10);`. – NathanOliver Mar 30 '22 at 13:03
  • @NathanOliver: Indeed it is. I'll remove, and upvote the better answer for good feelings. – Bathsheba Mar 30 '22 at 13:13