构造函数调用问题

Constructor invocation issue

在这段代码中,当尝试创建 dobj4 时遇到编译器错误

#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;
}

需要了解在 dobj2 的情况下传递字符串如何为名称调用构造函数,但在 dobj4 的情况下会导致错误。 如何解决这个问题?

我觉得你的问题可以有更短更容易理解的示例代码:(我也修复了它使其可编译)

即使继承与此处无关,我也保留了派生名称,并且我将其删除为不重要

#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;
}

转换构造函数的规则在 C++03C++11 中有所不同。

C++03中:只有一个参数的构造函数,或者在多个参数的情况下,其余参数具有默认值是隐式可转换的。

示例:

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

In C++11:上面C++03中定义的所有情况以及具有多个参数的构造函数。但是这样的构造函数调用需要brace-initialized.

示例:

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

不用说,如果声明了构造函数explicit,它就不会被转换。