簡體   English   中英

C ++如何在類函數內構造一個對象,做一些操作並返回值?

[英]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()函數將返回:

  • 例如返回{名= 0x007cad88“îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþ...}人&

顯然,在return命令中調用析構函數並刪除堆中的內存(因此我無法對指針進行任何進一步操作 - 它指向已釋放的內存 - 沒有數據)。

我的問題是 - 如何避免這種行為? 避免此類問題最優雅的方法是什么?

先感謝您!

  1. 使用string而不是char[]來避免使用new
  2. 返回Person而不是Person& ,因為本地范圍的類在它們離開范圍后被銷毀。 雖然這會導致副本發生,具體取決於編譯器設置。 這當然取決於提供適當的拷貝構造函數。
  3. 為了保證避免復制,請將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM