所以我在IDE CodeBlocks 13.12中创建了一个带有两个私有指针,两个setter,两个getter,一个构造函数和一个析构函数的简单类.对于普通变量,getter返回精确值,但使用指针返回一个奇怪的值,另一个返回精确值.
这是我班级的标题:
#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)这是我班级的来源
#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)这是我的主要功能
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)最后,这是我得到的值:
我的代码和对指针的理解有什么问题?谢谢
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)
我得到了确切的值:
a并且b在构造函数中是自动变量,因此在构造函数返回时会被销毁.
任何进一步访问re或im将导致未定义的行为.
既a没有b也没有在免费商店上分配,即使用new,所以delete没有意义,并且是未定义的行为.只需将析构函数留空; 对象将自动销毁而不会泄漏.
你正在经历的"好奇心"只是巧合; 未定义的行为是未定义的,因此它可能非常有效.
笔记:
你对指针的理解本身并没有错。问题是你不明白这里发生了什么:
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)
这段代码中发生的事情是加倍a并b在堆栈上分配。re和im被设置为指向的地址a和b分别。然后,当构造函数返回时,随着堆栈返回到调用函数,加倍a并b丢失。结果,re并im指向堆栈上的无效位置。
如果您绝对需要re并im成为指针,那么您需要像这样重写它:
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)