C ++:使用委派构造函数时,请选择`const char *`与std :: string`

时间:2018-06-20 14:54:54

标签: c++ string stl overloading delegating-constructor

请考虑以下内容:

class Foo {
public:
    Foo (const char *in) {
        printf ("C string constructor called\n");
    }
    Foo (std::string const &in) : Foo(in.c_str()) {
        printf ("C++ string constructor called\n");
    }
};
Foo bar ("I never asked for this");
//C string constructor called

因此,常量string被视为const char *

但是,如果我们将std::string构造函数设为“ primary”,会发生什么变化?

我们可以期望在不调用与C字符串相关的对象的情况下创建std::string对象并将其传递给相应的构造函数吗?

class Foo {
public:
    Foo (std::string const &in) {
        printf ("C++ string constructor called\n");
    }
    Foo (const char *in) : Foo(std::string (in)) {
        printf ("C string constructor called\n");
    }
};
Foo bar ("I never asked for this");
//C++ string constructor called
//C string constructor called

同样,C字符串构造函数被称为 first

此行为是在C ++标准中描述的还是与编译器相关的?

对于例如模板还是重载函数?

我使用GCC 7.3.0(MSYS2 x64)进行了编译。

3 个答案:

答案 0 :(得分:3)

"I never asked for this"string literal,由const char元素组成:

Foo bar ("I never asked for this"); // calls Foo (const char *in)

因此,Foo (const char *in)将始终通过重载决议被选择,无论您声明构造函数的“顺序”如何

如您第二个示例所示,

Foo (const char *in) : Foo(std::string (in))

delegating constructor被选中,并将调用初始化构造列表中唯一成员选择的目标构造函数

答案 1 :(得分:2)

在C ++中没有 primary 构造函数。

您观察到的是,首先执行了委托给构造函数(目标构造函数)的主体。然后是委托的构造函数的主体(委托构造函数)。

Delegating constructor

  

在这种情况下,目标构造函数由重载解析选择并首先执行,然后控件返回到委托构造函数并执行其主体。

答案 2 :(得分:1)

Overload ResolutionConstructor Delegation是完全互不影响的两个完全不同的事物。

重载解决方案在可能的情况下避免了隐式转换。

"I never asked for this"这样的字符串文字是const char[],它衰减为const char *。这与您的const char *构造函数完全匹配,因此被调用。用字符串文字作为输入来调用std::string构造函数将需要进行隐式转换,因为编译器将构造一个临时的std::string对象以绑定到std::string const &引用。

您改写了以下代码:

Foo bar (std::string("I never asked for this"));

或者这个:

std::string str = "I never asked for this";
Foo bar (str);

然后将调用std::string const &构造函数而不是const char *构造函数,因为没有从std::stringconst char *的隐式转换。

构造函数如何相互委托是一个实现细节,在编译器确定要调用哪个 构造函数之后。