首先,尽管编译器没有发出诊断消息,但类定义中的赋值运算符存在问题。
class foo{
private:
string str;
public:
foo operator = (string s){
str = s;
}
};
该代码无效,因为它的返回类型是foo
,但未返回任何内容。
建议改写为:
foo & operator = ( const std::string &s){
str = s;
return *this;
}
由于您没有声明默认构造函数或复制构造函数,编译器会隐式地代替您声明它们。因此,实际上您的类只有两个构造函数。其中一个是默认构造函数,其声明如下:
foo();
还有以下声明的复制构造函数
for( const foo & );
在这个声明中。
foo a = "this initialization throwing an error"
编译器假定右侧是一个类型为
foo
的对象,并且您将使用它来创建对象
a
。也就是说,在此声明中,编译器尝试应用隐式创建的复制构造函数。为此,它需要将字符串字面值转换为
foo
类型的对象。但是,该类没有转换构造函数,即无法接受字符串字面值作为参数的构造函数。因此,编译器会发出错误:
错误:请求将const char [38]转换为非标量类型'foo'
const char[33]
是声明右侧的字符串字面值的类型。
在这个代码片段中:
foo b;
b = "but assignment after declaration is working fine";
首先,使用编译器隐式定义的默认构造函数创建类型为foo
的对象b
,然后在第二个语句中使用了显式定义在类中的赋值运算符。根据运算符定义,它将数据成员str
分配给临时对象,该对象是从使用的字符串字面量构造的std::string
类型。这是可能的,因为类std::string
具有相应的转换构造函数。
foo(const std::string& s) : str(s) {}
。它可以将std::string
类型的参数转换为foo
类型的对象,并使用该参数来初始化foo
对象的成员变量str
。 - Fred Larson