Q:
#include <iostream>
#include <string.h>
using namespace std;
class szString {
int slen;
char *str;
public:
szString(const char *);
int len() const {
return slen;
}
};
// simple reference cannot bind to temp var
void Test(szString &a) {}
// Uncomment the following line to resolve.
void Test(const szString &a) {}
szString::szString(const char * newstr) : slen(0), str(NULL) {
slen=strlen(newstr);
str = new char[slen + 1];
//if (str)
//strcpy_s(str, (slen + 1), newstr);
}
int main() {
Test("hello");
getchar();
}
#include <string.h>
using namespace std;
class szString {
int slen;
char *str;
public:
szString(const char *);
int len() const {
return slen;
}
};
// simple reference cannot bind to temp var
void Test(szString &a) {}
// Uncomment the following line to resolve.
void Test(const szString &a) {}
szString::szString(const char * newstr) : slen(0), str(NULL) {
slen=strlen(newstr);
str = new char[slen + 1];
//if (str)
//strcpy_s(str, (slen + 1), newstr);
}
int main() {
Test("hello");
getchar();
}
// simple reference cannot bind to temp var
void Test(szString &a) {}
// Uncomment the following line to resolve.
void Test(const szString &a) {}
为什么void Test(const szString &a) {} 注解掉就编译错误 , 怎么不会去呼叫 void Test(szString &a) {} ?
const szString &a = "hello";
szString &a = "hello";
还有为什么 hello 字符串可以 assign 给 const szString &a ?
谢谢
void Test(szString &a) {}
// Uncomment the following line to resolve.
void Test(const szString &a) {}
为什么void Test(const szString &a) {} 注解掉就编译错误 , 怎么不会去呼叫 void Test(szString &a) {} ?
const szString &a = "hello";
szString &a = "hello";
还有为什么 hello 字符串可以 assign 给 const szString &a ?
谢谢
A:
1. 能够以单个类型为T的参数调用(包括只有1个参数,或者其余参数都有默认值)的类C的non-explicit构造函数,定义了一个T到C的隐式转换。
class C {
public:
/* non-explicit */ C(T v);
};
T v;
C c = v;
void f(C c);
f(v);
2. const引用能够绑定到临时对象, 并将临时对象的生命周期由"创建临时对象的完整表达式"提升至"绑定到的const引用超出作用域"。 non-const 引用没有这个功能(C++03)
void g(const C& c);
T v;
g( v ); 实际上是 g( C(v) );
通过C的单参数构造函数,构造了一个C的临时对象。
该临时对象绑定到g的参数c上, 并且该临时对象的生命周期被提升至c超出作用域 —— 即g返回处。
所以, 函数g中使用c是安全的。
void h(C& c);
T v;
h(v); 这是不行的。 即使显式调用构造函数也不行,如h( C(v) );
因为即使 h( C(v) ); 能够编译通过, C(v) 构造的临时对象, 将在创建它的完整表达式结束后销毁 —— non-const引用没有提升生命周期的作用。
也就是 h( C(v) ); 这个表达式 —— 进入h函数时, 参数c绑定的是一个已经被销毁的临时对象。
所以C++(03)禁止non-const引用绑定到临时对象, 所以 h( v); 或者 h( C(v) );不能被编译通过, 否则要出乱子。
这样是可以的:
T v;
C c = v; // 具名对象
h( c ); // 现在,h的参数绑定到的对象的生命周期一定不会比h调用过程短。
class C {
public:
/* non-explicit */ C(T v);
};
T v;
C c = v;
void f(C c);
f(v);
2. const引用能够绑定到临时对象, 并将临时对象的生命周期由"创建临时对象的完整表达式"提升至"绑定到的const引用超出作用域"。 non-const 引用没有这个功能(C++03)
void g(const C& c);
T v;
g( v ); 实际上是 g( C(v) );
通过C的单参数构造函数,构造了一个C的临时对象。
该临时对象绑定到g的参数c上, 并且该临时对象的生命周期被提升至c超出作用域 —— 即g返回处。
所以, 函数g中使用c是安全的。
void h(C& c);
T v;
h(v); 这是不行的。 即使显式调用构造函数也不行,如h( C(v) );
因为即使 h( C(v) ); 能够编译通过, C(v) 构造的临时对象, 将在创建它的完整表达式结束后销毁 —— non-const引用没有提升生命周期的作用。
也就是 h( C(v) ); 这个表达式 —— 进入h函数时, 参数c绑定的是一个已经被销毁的临时对象。
所以C++(03)禁止non-const引用绑定到临时对象, 所以 h( v); 或者 h( C(v) );不能被编译通过, 否则要出乱子。
这样是可以的:
T v;
C c = v; // 具名对象
h( c ); // 现在,h的参数绑定到的对象的生命周期一定不会比h调用过程短。