大家好,我又来提问关于 C++的问题了,我构造了一个类,这个类有自己的构造函数,和 copy assignment construtor。这个类的具体代码如下:
class HasPtr
{
friend void swap(HasPtr &, HasPtr &);
public:
void show() { cout << *ps << endl; }
HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) { cout << "string constructor" << endl; }
// HasPtr(const char *s) : ps(new std::string(s)), i(0) { cout << "char constructor" << endl; }
HasPtr(const HasPtr &orig) : ps(new string(*orig.ps)), i(orig.i) {}
string GetString() { return *ps; };
HasPtr &operator=(HasPtr);
~HasPtr()
{
delete ps;
}
private:
std::string *ps;
int i;
};
HasPtr &HasPtr::operator=(HasPtr hp)
{
swap(*this, hp);
return *this;
}
inline void swap(HasPtr &lhs, HasPtr &rhs)
{
cout << "swap" << endl;
using std::swap;
swap(lhs.ps, rhs.ps);
swap(lhs.i, rhs.i);
}
我发现使用构造函数时是可以正常触发从 const char* 到 string 的隐式转换,但是使用=号的时候却不可以,使用=号触发隐式转换的时候必须再加一个参数是 const char*的构造函数。
HasPtr hp1("Hello World!") // OK, 首先 const char* 隐式转换到 string 再调用 HasPtr 构造函数
HasPtr hp2 = "Hello World!" // 编译错误,无法将 const char* 转换到 string,所以 Hello World 无法隐式转换到 HasPtr!
同样是进行隐式转换, 为什么第二个就错了呢,对于第二个我的理解是,首先调用 copy assignment operator 这个函数,然后发现要将"Hello World"隐式转换到 HasPtr,这时候编译器发现最接近的构造函数是参数为 string 的那个,然后再触发"Hello World"到 string 的隐式转换最后调用 HasPtr 的构造函数构造 HasPtr 对象,再将右操作数赋值至左边,完成整个赋值。我这样是不是太强编译器所难了?
同时我发现如果添加一个 const char*的构造函数,就可以实现从 C 字符串到 HasPtr 对象的转化了,所以我上面思考的隐式转换顺序错在哪里了呢?
HasPtr::HasPtr(const char *s) : ps(new std::string(s)), i(0) {}
HasPtr = "Hello World" //编译通过!
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.