C++编译器VS2019和MinGW的问题:
最近在啃C++ Primer这本书,在学习到第14章重载运算符时,准备为自定义的类String重载一个输入运算符>>,代码如下所示:
//String.h头文件
#ifndef CPPLEARNING_STRING_H
#define CPPLEARNING_STRING_H
#include <memory>
#include <iostream>
class String {
friend std::ostream& operator<<(std::ostream& os,const String& s);
friend std::istream& operator>>(std::istream& is,String& s);
friend bool operator==(String a,String b);
friend bool operator!=(String a,String b);
public:
String():begin(nullptr),end(nullptr){}
String(const char* s);
String(const String& s);
//移动构造函数
String(String &&s) noexcept;
String& operator=(const String& s);
//移动赋值运算符
String& operator=(String &&s) noexcept;
void free();
const char* c_str() { return begin; }
size_t size() { return end - begin; }
size_t length() { return end - begin - 1; }
private:
char *begin;
char *end;
std::allocator<char> alloc;
private:
std::pair<char*, char*> alloc_n_copy (const char* beg, const char* end);
void range_initial(const char* first, const char* last);
};
std::ostream& operator<<(std::ostream& os,const String& s);
std::istream& operator>>(std::istream& is,String& s);
bool operator==(String a, String b);
bool operator!=(String a, String b);
#endif //CPPLEARNING_STRING_H
//String.cpp头文件
#include "String.h"
#include <cstring>
#include <iostream>
#include <utility>
using namespace std;
std::pair<char *, char *> String::alloc_n_copy(const char *beg, const char *end) {
auto data = alloc.allocate(end-beg);
return {data, uninitialized_copy(beg,end,data)};
}
void String::range_initial(const char *first, const char *last) {
auto newStr = alloc_n_copy(first,last);
begin = newStr.first;
end = newStr.second;
}
String::String(const char *s) {
range_initial(s,s+ strlen(s));
}
String::String(const String &s) {
range_initial(s.begin,s.end);
//cout<<"copy constructor\n";
}
void String::free() {
if(begin){
for(auto i = begin;i!=end;i++){
alloc.destroy(i);
}
alloc.deallocate(begin,end-begin);
}
}
String &String::operator=(const String &s) {
auto new_s = alloc_n_copy(s.begin,s.end);
free();
begin = new_s.first;
end = new_s.second;
// cout<<"copy-assignment operator"<<endl;
return *this;
}
String::String(String &&s) noexcept:begin(s.begin),end(s.end) {
s.begin = s.end = nullptr;
//cout<<"move constructor\n";
}
String &String::operator=(String &&s) noexcept {
if(this!=&s){
free();
begin = s.begin;
end = s.end;
s.begin = s.end = nullptr;
}
cout<<"move-assignment operator"<<endl;
return *this;
}
std::ostream& operator<<(std::ostream& os,const String& s){
auto c = s.begin;
while(c!=s.end){
os<<*c++;
}
return os;
}
std::istream& operator>>(std::istream& is,String& s){
if(!s.begin){
s = ""; //移动构造函数
}
auto c = s.begin;
char i;
while(is.get(i)){
if(i=='\n') break;
*c++ = i;
}
s.end = c;
return is;
}
bool operator==(String a, String b){
if(a.size()==b.size()){
auto c1 = a.begin,c2 = b.begin;
while(c1!=a.end){
if(*c1!=*c2){
return false;
}
c1++;c2++;
}
}
return true;
}
bool operator!=(String a,String b){
return !(std::move(a)==std::move(b));
}
关键代码就在于重载之后的>>运算符,我的策略是一次输入一个字符然后修改String引用类型对应的begin和end指针。运行如下的代码进行测试:
int main() {
String str;
cin>>str;
cout<<str;
}
在MinGW编译器编译后,代码的运行结果如下所示:
而使用VS2019编译器编译,代码则出现bug:
请问有无Cpp大佬能够解答这是什么原因,我其中使用了哪些未定义的操作?