构造函数调用问题

时间:2017-09-05 05:17:16

标签: c++ c++11 c++14 c++builder

在此代码中尝试创建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的情况下,它会导致错误。 如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

转换构造函数的规则因C++03C++11而异。

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

示例:

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

C++11中:上面C++03中定义的所有案例以及具有多个参数的构造函数。但是这样的构造函数调用需要大括号初始化

示例:

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

毋庸置疑,如果构造函数被声明为explicit,它就不会被转换。

答案 1 :(得分:1)

我觉得你的问题可以缩短并且更容易理解示例代码:(我还修复了以使其可编辑)

我保留了派生名称,即使继承在这里没有相关性,我已将其删除为不重要

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