[英]C++ How can I construct an object inside a class function, do some operations and return the value?
我不打算通過整個源代碼,因為它是1000多行,但我特意構建了一個關於我感興趣的事情的類似案例。注意這個源代碼:
#include <iostream>
using namespace std;
class Person
{
public:
Person();
Person(char*);
~Person();
Person& operator=(const Person&);
friend Person& example(const Person&);
void print() const;
private:
char* name;
};
Person::Person()
{
name = new char[12];
name = "Temp";
}
Person::~Person()
{
delete[] name;
}
Person::Person(char* _name)
{
name = new char[strlen(_name)+1];
strcpy_s(name,strlen(_name)+1,_name);
}
Person& example()
{
char* TestName = new char[11];
TestName = "ShouldStay";
Person B(TestName);
return B;
}
void Person::print() const
{
cout << name;
}
int main()
{
example();
return 0;
}
在這種情況下,example()函數將返回:
顯然,在return命令中調用析構函數並刪除堆中的內存(因此我無法對指針進行任何進一步操作 - 它指向已釋放的內存 - 沒有數據)。
我的問題是 - 如何避免這種行為? 避免此類問題最優雅的方法是什么?
先感謝您!
string
而不是char[]
來避免使用new
。 Person
而不是Person&
,因為本地范圍的類在它們離開范圍后被銷毀。 雖然這會導致副本發生,具體取決於編譯器設置。 這當然取決於提供適當的拷貝構造函數。 為了保證避免復制,請將example
的簽名更改為:
void example(Person& person)
並填寫函數內輸入人員的字段。 該Person
的范圍將綁定到調用范圍(或您構造它的任何其他位置)。 這種方法有缺點,例如你不能將結果鏈接在一起。
您的代碼包含許多邏輯錯誤:
Person::Person()
{
name = new char[12];
name = "Temp";
}
在上面的函數中,您分配了一個包含12個元素的char數組,然后您只需忘記它,而是將name
指向字符串文字。
Person::~Person()
{
delete[] name;
}
whoopps。 如果Person
是從默認構造函數構建的,則會delete
字符串文字。 C ++中的禁忌。
Person::Person(char* _name)
{
name = new char[strlen(_name)+1];
strcpy_s(name,strlen(_name)+1,_name);
}
不是100%確定strcpy_s
是什么,但在這種情況下代碼分配一個數組,似乎將字符串復制到數組中。 這似乎沒問題(但只是strcpy(name, _name);
由於很多原因會更好)。
Person& example()
{
char* TestName = new char[11];
TestName = "ShouldStay";
Person B(TestName);
return B;
}
這段代碼嚴重破壞了。 首先,它通過引用返回一個臨時對象。 一個非常糟糕的主意。 它還分配了一個數組,並再次忘記它並使用字符串文字。
讓代碼工作的最優雅方式(實際上是我認為唯一的方法)是首先了解C ++的基礎知識是如何工作的。 你應該首先從頭到尾閱讀一本好的C ++書籍 ,然后才能開始用C ++編寫代碼。
你的1000行源代碼很可能只是垃圾。 我不是說你是愚蠢的,只是因為你不了解C ++的基礎知識。 首先通過閱讀來照顧它們,而不是試驗編譯器。
您無法通過實驗來學習C ++,原因有兩個:
由於它的歷史,這是一個復雜的,有時甚至是完全不合邏輯的語言。 猜測幾乎總是一個糟糕的舉動。 無論你多么聰明,你都無法正確猜出委員會的決定。
當你犯了一個錯誤時,天使沒有運行時錯誤告訴你。 很多時候,顯然程序仍然有效......直到它由你的老師,老板或配偶經營。 通過編寫代碼並觀察發生的事情來猜測C ++規則是無稽之談。
Person& example()
{
char* TestName = new char[11];
TestName = "ShouldStay";
Person B(TestName);
return B;
}
上面在堆棧上創建了一個Person實例,作用於該函數。 因此,當函數返回時,將調用Person的析構函數,並返回對已銷毀對象(在堆棧上)的引用。
此外,您應該考慮返回Person的副本,或者您需要使用new運算符在堆上創建person的實例並返回指向該實例的指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.