How can one constructor call another in C++?

I know this is not possible in earlier versions of C++. However, I don't know if it is supported now.

I have the following constructors:

int_vector::int_vector();

int_vector::int_vector(int i);

int_vector::int_vector(int* int_array, int int_array_size);

when the third constructor is called with int_array_size of 0, I want the object to call the first constructor instead. Is this valid in moden C++?

I could of course just have 1 construtor of the third type with default values of parameters as nullptr and 0 and it will still cover the first two constructor types. I am aware of that, I just want to know how one constructor can call another.
Hi,
> When the third constructor is called with array_size of 0, I want the object to call the first constructor instead

You may try :
1
2
3
4
5
6
int_vector::int_vector(int* int_array, int int_array_size){
    if(array_size == 0)
    {
        new (this) int_vector(); return;
    }
}


Be sure to include <memory>
It is called "placement new"
Last edited on
Does that help you? :)
Constructors can call one another since C++11 (it's called "delegating constructor": http://en.cppreference.com/w/cpp/language/initializer_list#Delegating_constructor ), but this delegation is unconditional:
1
2
3
4
5
6
// always call int_vector() first, and then maybe do more work
int_vector::int_vector(int* int_array, int int_array_size) : int_vector() {
    if(int_array_size > 0) {
        // extra work
    }
}


If your default ctor simply initializes a few members, you can drop it entirely and just use the default member initializers:
1
2
3
4
5
6
7
8
9
struct int_vector {
    int* p = nullptr;
    int sz = 0;
    int_vector(int* int_array, int int_array_size) {
        if(int_array_size > 0) {
            // extra stuff
        }
    }
};

Last edited on
if I use "new" that means a copy is created and sent back which means that a copy or move constructor shall be needed to copy the temporary object. Is that correct?
Last edited on
> If I use "new" that means a copy is created and sent back which means that a copy or move constructor shall be needed to copy the temporary object.

No, that is not true.

Placement new constructs an object directly on the place you specified. No temporary object or additional constructor call involved.
You shouldn't use new at all, consider smart pointers instead: unique_ptr or shared_ptr

The main problem with new is that it's corresponding delete is never reached when an exception is thrown.
closed account (48T7M4Gy)
.
Last edited on
closed account 5a8Ym39o6 wrote:
You may try :

1
2
3
4
5
6
int_vector::int_vector(int* int_array, int int_array_size){
    if(array_size == 0)
    {
        new (this) int_vector(); return;
    }
}


This is not safe, generally speaking. And since we haven't seen the class internals, we can't know whether it is safe in this instance or not.
@kemort

Sure, that's fine for a constructor. The details as I understand them is that the object isn't deemed to exist until a constructor is completed, so not too much auto-magical about that. Also, one can have a function try block in the constructor, so an exception there can be caught.

But what of the situation where the exception is thrown elsewhere? As in a member function. In that case the destructor isn't reached, and we have a memory leak.

Any way it has been said many times on this forum that use of new / delete is bad.

Here is one of the relevant parts from C++ Core Guidelines:

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Rr-newdelete
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Rr-owner

The whole chapter about resource management is worth reading, if anyone has any doubt.
closed account (48T7M4Gy)
.
Last edited on
The term auto-magic is Stroustrup's, not mine.


No worries :+) I wasn't trying to attribute it to you, it was inside a quote.

The implication to me was that despite his code snippet which covers the point you initially raised, .....


Well I don't think it does cover the point I raised: the example is specifically to do with a constructor; I meant in general.

.... he seems to be saying that the action covered by it is done behind the scenes


Yes it is. But as I understand it, it doesn't apply outside of a constructor.

I was hesitant about the constructor aspect too before I posted but on reflection, but without checking, I don't think it matters whether a class of some sort or a simple ol' new char, new int etc was involved.


Theoretically it does matter whether it is a class or not. But if new fails for a char or int, then I guess one has bigger problems :+D. But the point was to not use new or delete ever.

However that is tempered in my mind when some poor bugger is faced with more basic constraints from school etc and someone saying don't use new/delete doesn't get marks in semeseter 1 as you probably know.


Yes well that is a problem, people still teach new / delete, along with using namespace std; Why can't they teach it properly? Maybe partially because they are too scared to update their syllabus to C++11? Why teach them new when they are going to have to abandon it as soon as they start work? Hopefully earlier. Some schools still insist on C++03 code, so by February next year with C++17, they will be 14 years and 3 versions of the standard behind.

But you are right, if some student makes use of std::unique_ptr, their teacher is bound to ask where they learned that from. I just wish that teachers would accept that something valid has been learnt from elsewhere.

With the constraints from the schools, I think we (cplusplus respondents) are sometimes at cross purposes with the teachers here. Using things like std::vector instead of arrays is a solid technique that differentiates C++ from C, but the teachers want the students to learn all the different aspects. Same story with pointers. Part of the trouble there is the big difference between C and C++, courses are often a combination of the two.

Anyway all of this is off topic, but I hope there has been a little bit of education all round - me included :+)
Topic archived. No new replies allowed.