#include <iostream>
#include <cstring>
using namespace std;
class String{
friend ostream &operator<<(ostream&, const String&);
public:
String(const char* ="");
String(const String &);
~String();
String operator()(int,int=0)const;
String operator++(int);
private:
int length;
char *sPtr;
void setString(const char *);
};
ostream &operator<<(ostream &output,const String &s){
output<<s.sPtr;
return output;
}
String::String(const char *s):length(s !=0 ? strlen(s):0){
cout<<"呼叫默認建構式,一般建構式,轉換建構式"
<<s<<endl;
setString(s);
}
String::String(const String &cpy):length(cpy.length){
cout<<"呼叫拷貝建構式"<<cpy.sPtr<<endl;
setString(cpy.sPtr);
}
String::~String(){
cout<<"呼叫解構式:"<<this->sPtr<<endl;
delete[] sPtr;
}
String String::operator()(int index,int subLenght)const{
if(index<0 || index >= length || subLenght<0) return "";
int len;
if((subLenght ==0)|| (index+ subLenght >length))
len= length -index;
else
len=subLenght;
char *tempPtr= new char[len+1];
strncpy(tempPtr,&sPtr[index],len);
tempPtr[len]='\0';
String tempString(tempPtr); //這里觸發轉換建構式
delete []tempPtr;
return tempString; //回傳時觸發拷貝建構式
}
String String::operator++(int a){
String tmp(*this); //這里觸發拷貝建構式
++this->length;
return tmp; //為什么里不像上面那個函式回傳時觸發拷貝建構式
}
void String::setString(const char *string2){
sPtr=new char[length+1];
if(string2 !=0)
strcpy(sPtr,string2);
else
sPtr[0]='\0';
}
int main()
{
String s1("11111");
String s2("22222");
cout<<s2++<<endl; //多載++和多載下面()
cout<<s1(4,20)<<"\n\n";
}
uj5u.com熱心網友回復:
《C++編程思想》uj5u.com熱心網友回復:
我不知道你用的是什么編譯vs2019 debug下兩者都呼叫了2次拷貝構造 releas下倆個都只掉用一次
gcc4.9.2在c++11模式打開的情況下,都呼叫一次
呼叫一次的原因是NRVO復制消除,vs deubg不支持nrvo 支持rvo,所以debug下兩次
gcc 默認支持nrvo,所以一次
uj5u.com熱心網友回復:
是用gcc5.1 就是多載() 時除錯return tempString 會呼叫拷貝建構式符合拷貝構造說明,但多載++除錯時return tmp 同樣是回傳物件,卻沒有呼叫拷貝建構式uj5u.com熱心網友回復:
趙老師,知道是第幾章有說明嗎,一本書去找也不容易
我就是看書上說的回傳如果是物件,如果不是參考話就會呼叫拷貝構種造函式,但這里結果卻不同
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
我不知道你用的是什么編譯
vs2019 debug下兩者都呼叫了2次拷貝構造 releas下倆個都只掉用一次
gcc4.9.2在c++11模式打開的情況下,都呼叫一次
呼叫一次的原因是NRVO復制消除,vs deubg不支持nrvo 支持rvo,所以debug下兩次
gcc 默認支持nrvo,所以一次
網上搜一下NRVO復制消除,知道是一種優化方式,但是同一個檔案內的函式,怎么一個會用到NRVO復制消除,另一個卻沒有,要說NRVO復制消除對同一個檔案下函式應該一樣處理
uj5u.com熱心網友回復:
發現如果 if(index<0 || index >= length || subLenght<0) return ""; 這行如果注釋掉,結果就和多載++ 的一樣了同樣在多載++函式改成這樣,++函式在回傳時也會呼叫拷貝構函式
String String::operator++(){
if(length=0) return ""; //加上這一句,不管有沒執行 最后一句return tmp就會再呼叫一次拷貝建構式 估計是return "" 造成的不知道為什么
char *tempPtr= new char[8];
strcpy(tempPtr,"123456");
String tmp(tempPtr);
delete []tempPtr;
++this->length;
return tmp;
}
uj5u.com熱心網友回復:
// x.cpp : 此檔案包含 "main" 函式。程式執行將在此處開始并結束。以上是我給略微精簡的代碼,把不要的輸出都注釋了,只留下拷貝建構式中的輸出
//
#include <iostream>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;
class String {
friend ostream& operator<<(ostream&, const String&);
public:
String(const char* = "");
String(const String&);
~String();
String operator()(int, int = 0)const;
String operator++(int);
private:
int length;
char* sPtr;
void setString(const char*);
};
ostream& operator<<(ostream& output, const String& s) {
output << s.sPtr;
return output;
}
String::String(const char* s) :length(s != 0 ? strlen(s) : 0) {
//cout << "呼叫默認建構式,一般建構式,轉換建構式" << s << endl;
setString(s);
}
String::String(const String& cpy) : length(cpy.length) {
cout << "呼叫拷貝建構式" << cpy.sPtr << endl;
setString(cpy.sPtr);
}
String::~String() {
//cout << "呼叫解構式:" << this->sPtr << endl;
delete[] sPtr;
}
String String::operator()(int index, int subLenght)const {
if (index < 0 || index >= length || subLenght < 0) return "";
int len;
if ((subLenght == 0) || (index + subLenght > length))
len = length - index;
else
len = subLenght;
char* tempPtr = new char[len + 1];
strncpy(tempPtr, &sPtr[index], len);
tempPtr[len] = '\0';
String tempString(tempPtr); //這里觸發轉換建構式
delete[]tempPtr;
return tempString; //回傳時觸發拷貝建構式
}
String String::operator++(int a) {
String tmp(*this); //這里觸發拷貝建構式
++this->length;
return tmp; //為什么里不像上面那個函式回傳時觸發拷貝建構式
}
void String::setString(const char* string2) {
sPtr = new char[length + 1];
if (string2 != 0)
strcpy(sPtr, string2);
else
sPtr[0] = '\0';
}
int main()
{
String s1("11111");
String s2("22222");
cout << s2++ << endl; //多載++和多載下面()
cout << s1(4, 20) << "\n\n";
}
以下是我在vs2019 和 gcc 5.1.0下的運行結果,與你說的不一致
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
就是搞不懂return tempString 多載()函式會加載一次拷貝建構式, 而多載++函式 return tmp;就不會,估計是開頭的 if(index<0 || index >= length || subLenght<0) return ""; 這行問題,我把這行加到++函式中發現回傳也會多載加載一次拷貝建構式
uj5u.com熱心網友回復:
趙老師:c++編程思想這書中是不是這行相反,“回傳臨時物件”的方式是完全不同
的。當編譯器看到我們這樣做時,它明白對創建
的物件沒有其他需求,只是回傳它,所以編譯器
直接地把這個物件創建在外部回傳值的記憶體單
元。因為不是真正創建一個區域物件,所以僅需
要一個普通建構式呼叫(不需要拷貝構造函
數),且不會呼叫解構式。這種方法不需要什
么花費,因此效率是非常高的,但程式員要理解
這些。這種方式常被稱作回傳值優化(return
value optimization)。
這好像也不像
uj5u.com熱心網友回復:
用vs2013跟蹤一下不管有沒有 return "" 兩個在return時都會呼叫拷貝建構式,gcc多載()沒優化,多載++優化掉了。。。暈轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/249145.html
標籤:新手樂園
上一篇:C語言中三角函式呼叫失敗
下一篇:請教到底什么是函式原型,謝謝
