anshkun
anshkun

Reputation: 115

Constructor invocation issue

In this code when try to create dobj4 got compiler error

#include<iostream>
using namespace std;
class mod;
class  name {
    friend mod;
    public:
            name(const char* n) {
                    cout << "1 arg constructor for name\n";
            }
            name() {
                    cout << "no arg constructor for name\n";
            }
            name(const char* n, int i ){
                    cout << "2 arg constructor for name\n";
            }
      };

class mod {
    public:
    mod() {
            cout << "base class constructor invoked\n";
    }
};

struct derived : mod {

    derived(name) {
            cout << "derived constructor invoked\n";
    }
 };

int main() {
    name nobj;
    derived dobj(nobj);

    name nobj1("hello");
    derived dobj1(nobj1);

    derived dobj2("Hi");

    name nobj2("yo", 2);
    derived dobj3(nobj2);

 //      derived dobj4("go", 4);

    return 0;
}

Need to understand how when pass strings invoke constructor for name in case of dobj2 but in case of dobj4 it is causing error. How to correct this issue?

Upvotes: 0

Views: 107

Answers (2)

CinCout
CinCout

Reputation: 9619

The rule for converting constructors varies in C++03 and C++11.

In C++03: Constructors with only one argument, or in case of more than one arguments have rest of the arguments with a default value are implicitly convertible.

Example:

name(const char* n) {}
name(int n, int i = 0) {} // i has a default value

In C++11: All the cases defined in C++03 above along with constructors with more than one argument. But such constructor calls needs to be brace-initialized.

Example:

derived dobj4({"go", 4}); // call to name(const char* n, int i) is brace-initialized

Needless to say, if the constructor is declared explicit, it won't be converting.

Upvotes: 3

Artemy Vysotsky
Artemy Vysotsky

Reputation: 2734

I feel like your question could have a lot shorter and easier to understand sample code: (I also fixed to make it compilable)

I left the derived name even if the inheritance has no relevance here and I have removed it as not important

#include<iostream>
class  name {
public:
    name() {
        std::cout << "no arg constructor for name\n";
    }
    name(const char* n) {
        std::cout << "1 arg(" << n <<") constructor for name\n";
    }
    name(const char* n, int i ) {
        std::cout << "2 arg(" << n << ',' << i <<") constructor for name\n";
    }
};
struct derived {

    derived(const name& n ) {
        std::cout << "derived name constructor invoked\n";
        (void)n;
    }
};

int main() {

    name nobj;
    derived dobj(nobj);

    derived dobj2("Hi");

    derived dobj4({"go", 4}); //see the initialization list instead of 2 parameters passing

    return 0;
}

Upvotes: 1

Related Questions