簡體   English   中英

(C++ OOP) 當我將它的指針分配給一個新值時,為什么 name[] 沒有改變?

[英](C++ OOP) Why name[] is not changing when I assign its pointer to a new value?

我是 C++ OOP 概念的新手,我來自 Java OOP 背景。 我已經嘗試過this->name=name但出現錯誤,然后我嘗試使用指針,但是,即使代碼運行,它也不會“保存”對象名稱中的名稱。

#include <iostream>
using namespace std;

class Person{
private:
    char name[];
    int age;
public:
    Person(char name[], int age){
        char* pName=this->name;
        pName=name;

        this->age=age;
        cout<<this->name;
    }
    getInformation(){
        cout<<"name: "<<this->name<<" age: "<<this->age;
    }

};

int main(){
Person foo("foo",5);
}

在 C++ 中,數組通常需要聲明一個長度——在這種情況下, char name[]將是無效的。

此外,聲明為int array[5] (具有大小)的int array[5]不能直接賦值。 即這是無效的:

class A
{
public:
    int array[5];

    void foo() {
        int other_array[5] = {0, 0, 0, 0, 0};
        this->array = other_array;
    }
}

相反,您需要一次為每個元素分配一個(例如在循環中):

for(int i = 0; i < 5; ++i) this->array[i] = other_array[i];

這是因為在 C++ 數組中所有元素都有空間,這與 Java 不同,其中char name[]是指向數組的指針。 如果您希望能夠直接更改變量引用的數組,則應改用指針 - 指針可以像數組一樣取消引用:

class A
{
public:
    int *array;

    int foo(int *other_array) {
        this->array = other_array;
    }
}

但是,如果您這樣做,請注意內存管理。

忽略(暫時)代碼無效且無法編譯的事實; 這里:

    char* pName=this->name;

您實例化一個本地指針並將未初始化的指針name分配給它。 然后立即使用指向參數name的指針重新分配它:

    pName=name;

但是pNamename都是臨時的,並且是指向字符串的指針,而不是字符串本身。 此外pName不是對this->name引用 因此,從Person()構造函數返回時,對象保持不變(並且未初始化)。 您可能打算:

    char*& pName = this->name ;
    pName = name ;

但這只是一種復雜的形式:

    this->name = name ;

並且仍然是不明智的,因為您然后將this->name分配給main()中的文本字符串"foo"的地址,即const 在任何情況下,您都為Person了一個指向屬於其他事物且不由Person “擁有”的數據的指針,而Person不知道數據的生命周期或有效性。 它是各種錯誤和不良行為的秘訣。

空終止(或 ASCII 或 C 風格)字符串不是真正的數據類型; 它只是一個字符數組約定。 此外,數組甚至不是 C++ 中的一流數據類型,您不能將一個數組分配給另一個數組或將數組作為函數參數按值傳遞 - 相反,賦值和參數傳遞是指針操作 Person()name是指向字符串常量"foo"第一個字符的指針,而不是包含"foo"的獨立字符串。

要使用 C 樣式字符串更正此問題:

#include <iostream>
#include <cstring>

class Person
{
    private:
        char name[256];   // << Must have size here.
        int age;

    public:
        Person( const char* name, int age)   // << Must have const arg for "foo" to be a valid parameter.
        {
            std::strncpy( this->name,        // << C strings must be explicitly copied, not "assigned".
                          name, 
                          sizeof(this->age) - 1 ) ;
            this->age = age;
        }

        void getInformation() const   // << must have return type, and may be const.
        {
            std::cout << "name: " << this->name << " age: " << this->age << "\n" ;
        }

} ;

然而,在大多數情況下,最好使用 C++ std::string對象:

#include <iostream>
#include <string>      // << Use C++ string library 
                       //    (i.e. string rather than cstring/string.h)

class Person
{
    private:
        std::string name;     // << std::string memory management is intrinsic
        int age;

    public:
        Person( const std::string name, int age)
        {
            this->name = name ;  // << Assignment possible due to
                                 //    operator overloading
            this->age = age;
        }

        void getInformation() const
        {
            std::cout << "name: " << this->name << " age: " << this->age << "\n" ;
        }

} ;

如上所述,std::string 目前是推薦的。 不僅對於這個問題,std::string 在很多情況下都非常適合使用。 尤其是在學習方面。

只需從 MS 的站點查看此處的字符串類: https : //docs.microsoft.com/en-us/cpp/standard-library/basic-string-class?view=vs-2019

如果您使用的是c++ ,最好使用std::string來處理字符串。 但是回答您的問題,當您為任何變量賦值時,它會覆蓋其先前的值並獲得一個新值。

在您的代碼中:

char* pName=this->name;
pName=name;

第一行為pName變量分配一個新值。 第二行,簡單地覆蓋你的第一行,並將一些新的東西復制到你的pName變量中。 所以,這不是您想要做的正確方法。

如果您想要一個char *變量並將另一個char *內容復制到其中,我建議如下:

private:
    char *name;
    ...
public:
    Person(char name[], int age){
        this->name = strdup(name);
        ...
    }

並注意釋放析構函數中name內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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