为什么私有 class 中的指针变量不能指向 class 的外部变量

why pointer variable inside private class can't point to outside variable of class

#include<iostream>
#include <string>

using namespace std;

class Human
{
    private:
        int *age;
        string *name;
    
    public:
        Human(string p_name, int value)
        {
            
            *name = p_name;
            *age = value; 
            cout <<"Name of Person is "<<*name <<" and age is "<<*age<<endl;
        }

        ~Human()
        {
            delete name;
            delete age;

            cout<<"Destructor release all memory So now name is "<<*name << " and age is "<<*age<<endl;
        }

        void display()
        {
            cout << "The name is "<<*name <<" and age is "<<*age<<endl;
        }
};

int main()
{
    int age = 24;
    string name = "CODY";
    Human cody(name,age);
    cody.display();
}

它没有打印任何东西……有人能解释一下吗……是不是因为我错误地实现了指针变量……为什么不正确请告诉我然后会是什么替代解决方案

why pointer variable inside private class can't point to outside variable of class

你问题的前提是错误的。私有成员变量 可以 指向 class.

之外
    Human(string p_name, int value)
    {
        
        *name = p_name;
        *age = value;

您没有初始化指针,因此通过它们进行间接访问会导致未定义的行为。不要这样做。

cout << "The name is "<<*name <<" and age is "<<*age<<endl;

在这里,您通过无效指针间接执行,程序的行为未定义。

        delete name;
        delete age;

        cout<<"Destructor release all memory So now name is "<<*name << " and age is "<<*age<<endl;

即使指针没有失效,删除它们也是错误的。您没有通过分配 new 创建任何对象,因此没有要删除的内容。删除未通过分配 new 返回的指针将导致未定义的行为。不要这样做。

此外,即使 delete 有效,这也会使指针无效,并且通过 cout 语句中新无效指针的连续间接寻址将导致未定义的行为。也不要这样做。

解决方案:删除 delete 行。


class 指向class 外部变量的解决方案:为了引用函数外部的对象,您需要使用间接寻址。例如,您可以使用指针参数,并将成员初始化为指向相同的对象:

Human(string* p_name, int* value)
    : name(p_name), age(value)
    {}

// example usage:
Human cody(&name, &age);

请注意,在成员中存储指针是不稳定的,因为您必须了解指向对象和包含指针的对象的相对生命周期。您必须确保指针的寿命不会超过指向的对象。

考虑到你的class的引用设计问题,我劝你考虑改用值。一般来说,这可能更有用 class:

struct Human {
    std::string name;
    int age;

    void display()
    {
        std::cout
            << "The name is "
            << name
            << " and age is "
            << age
            << '\n';
    }
};

int main()
{
    Human cody {
        .name="CODY",
        .age=24,
    };
    cody.display();
}

您给出的程序中有几个错误,如下所述。

错误 1

首先你需要确保数据成员agename指向一些适当类型的变量。然后只有您可以取消引用它们。由于您正在取消引用未指向适当类型对象的指针,因此您的程序中有 未定义的行为

Human(string p_name, int value)
        {
            
            *name = p_name; //Undefined behavior because name doesn't point to an std::string object
            *age = value; //Undefined behavior because age doesn't point to an int object
            cout <<"Name of Person is "<<*name <<" and age is "<<*age<<endl;
        }

错误 2

其次当你使用new分配内存后,你可以使用delete。并且由于您没有使用 new 分配任何内存,因此使用 delete.

是不正确的
~Human()
        {
            delete name; //not valid 
            delete age;  //not valid

            cout<<"Destructor release all memory So now name is "<<*name << " and age is "<<*age<<endl; //undefined behavior as explained in mistake 3
        }

错误 3

第三 你在对它们使用 delete 之后取消对指针 agename 的引用。这再次导致 未定义的行为

cout<<"Destructor release all memory So now name is "<<*name << " and age is "<<*age<<endl; //undefined behavior because you just used `delete` on the pointers and also because they don't point to objects of the appropriate type

更好的方法是使用智能指针,它会为您管理内存。也就是说,当我们使用智能指针时,我们不必手动使用 newdelete.


为了让您了解如何更正当前的 2 个错误,您可以参考下面给出的修改示例:

//this uses constructor initializer list 
Human(string p_name, int value): age(new int(value)), name(new std::string(p_name))
{
    
    cout <<"Name of Person is "<<*name <<" and age is "<<*age<<endl;
}
//destructor 
~Human()
{
    if (name != nullptr && age!=nullptr)
    {   //check that 
        delete name;
        delete age;
            
        cout<<"delete used successfully"<<endl;
                
     }
     else 
     {
        cout<<"delete not used"<<endl;
     }
            
     }