返回奇怪值的类中的C++指针

Gro*_*beu 1 c++ pointers

所以我在IDE CodeBlocks 13.12中创建了一个带有两个私有指针,两个setter,两个getter,一个构造函数和一个析构函数的简单类.对于普通变量,getter返回精确值,但使用指针返回一个奇怪的值,另一个返回精确值.

  1. 这是我班级的标题:

    #ifndef COMPLEXE_H_INCLUDED
    #define COMPLEXE_H_INCLUDED
    
    #include <iostream>
    
    class Complexe{
    public:
        Complexe(const double re = 0.0, const double im = 0.0);
        ~Complexe();
    
        double getReel() const;
        double getImag() const;
    
        void setReel(double);
        void setImag(double);
    
    private:
        double* re;
        double* im;
    
    };
    
    #endif // COMPLEXE_H_INCLUDED
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这是我班级的来源

    #include "complexe.h"
    
    Complexe::Complexe(const double re, const double im)
    {
        double a = re;
        double b = im;
    
        this->re = &a;
        this->im = &b;
    }
    
    Complexe::~Complexe()
    {
        delete re;
        delete im;
    }
    
    double Complexe::getReel() const
    {
        return *re;
    }
    
    double Complexe::getImag() const
    {
        return *im;
    }
    
    void Complexe::setReel(double a)
    {
        *this->re = a; 
    }
    
    void Complexe::setImag(double a)
    {
        *this->im = a; 
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 这是我的主要功能

    int main()
    {
        Complexe cpl1(12, 3);
        cout << "C1 | " << "Re : " << cpl1.getReel()
           << ", Im : " << cpl1.getImag()
           << endl;
    
        cpl1.setReel(50);
        cpl1.setImag(50);
    
        cout << "C1 | " << "Re : " << cpl1.getReel()
            << ", Im : " << cpl1.getImag()
            << endl;
    
        Complexe * cpl2 = new Complexe(20,20);
        cout << "C2 | " << "Re : " << cpl2->getReel()
            << ", Im : " << cpl2->getImag()
            << endl;
    
        return 0;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 最后,这是我得到的值:

结果

我的代码和对指针的理解有什么问题?谢谢

PS:奇怪的是,当我将构造函数代码更改为:

Complexe::Complexe(const double re, const double im)
{
    double a = re;
    double b = im;

    this->re = &a;
    this->im = &a; // &a here too // or &b in both
}
Run Code Online (Sandbox Code Playgroud)

我得到了确切的值:

结果与参考相同

cad*_*luk 7

  1. a并且b在构造函数中是自动变量,因此在构造函数返回时会被销毁.
    任何进一步访问reim将导致未定义的行为.

  2. a没有b也没有在免费商店上分配,即使用new,所以delete没有意义,并且是未定义的行为.只需将析构函数留空; 对象将自动销毁而不会泄漏.

你正在经历的"好奇心"只是巧合; 未定义的行为是未定义的,因此它可能非常有效.


笔记:

  • 正如@LightnessRacesinOrbit在您的问题的评论中所述,您可以使用不需要它们的指针.只需将参数复制到成员函数就足够了,肯定会使代码看起来更干净.当然,它可以工作,但这样的指针使用并不会影响性能,只是......是的,毫无意义.

  • _"That 'curiosity' [you're] experiencing is just a coincidence"_ rofl.. lesson for life! (2认同)

Xir*_*ema 5

你对指针的理解本身并没有错。问题是你不明白这里发生了什么:

Complexe::Complexe(const double re, const double im)
{
    double a = re;
    double b = im;

    this->re = &a;
    this->im = &b;
}
Run Code Online (Sandbox Code Playgroud)

这段代码中发生的事情是加倍ab在堆栈上分配。reim被设置为指向的地址ab分别。然后,当构造函数返回时,随着堆栈返回到调用函数加倍ab丢失。结果,reim指向堆栈上的无效位置。

如果您绝对需要reim成为指针,那么您需要像这样重写它:

Complexe::Complexe(const double re, const double im)
{
    this->re = new double(re);
    this->im = new double(im);
}
Run Code Online (Sandbox Code Playgroud)

然后你需要确保你包含在析构函数中:

Complexe::~Complexe()
{
    delete re;
    delete im;
}
Run Code Online (Sandbox Code Playgroud)