构造函数调用问题
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++03
和 C++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
,它就不会被转换。
在这段代码中,当尝试创建 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++03
和 C++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
,它就不会被转换。