关于这段程序的几个疑问
来源:4-1 字符语法的常见陷阱上
lihsing
2022-12-09
老师,您好,我刚刚学完咱们这个课程的基础部分,我写了一个这样的小程序,
目的是为了对一个vector求均值时,避免重复计算,程序如下:
#include <vector>
#include <iostream>
class Q {
public:
Q(): sum_(nullptr), mean_(nullptr) {}
void Append(double &i) {
data_.push_back(i);
}
double Sum() {
if (sum_ == nullptr) {
std::cout << "求和..." << std::endl;
double temp = 0;
for (auto it=data_.begin(); it!=data_.end(); it++) {
temp += (*it);
}
sum_ = new double(temp);
}
return *sum_;
}
double Mean() {
if (mean_ == nullptr) {
std::cout << "求均值..." << std::endl;
mean_ = new double(Sum() / data_.size());
}
return *mean_;
}
void Clean() {
if (sum_ != nullptr) {
delete sum_;
sum_ = nullptr;
}
if (mean_ != nullptr) {
delete mean_;
mean_ = nullptr;
}
}
~Q() {
Clean();
}
private:
std::vector<double> data_;
double *sum_;
double *mean_;
};
int main() {
Q q;
double d1 = 1.0;
double d2 = 2.0;
double d3 = 3.0;
double d4 = 4.0;
q.Append(d1);
q.Append(d2);
q.Append(d3);
q.Append(d4);
std::cout << q.Mean() << std::endl;
std::cout << q.Mean() << std::endl;
}
我有这样几个问题:
问题1
对于Sum方法
和Mean
方法,由于方法内部计算出来的结果,需要在函数外部用到,是否必须使用new
在堆区进行创建?
问题2
- 一个类的析构方法是否是为了删除该类在堆区产生的变量?
- 如果一个类没有在堆区创建变量,是否可以不写析构方法或者写一个空方法?
例如:
class A1 {
public:
A1() {
i = 1;
j = 2;
}
private:
int i;
int j;
}
class A2 {
public:
A2() {
i = new int(1);
j = new int(2);
}
~A2() {
delete i;
i = nullptr;
delete j;
j = nullptr;
}
private:
int *i;
int *j;
}
A1因为没有堆区的变量,不写析构方法不会造成内存泄漏,而A2则必须写。
问题3
Append方法
由于参数是一个引用,直接这样调用不行:
q.Append(5.0);
而必须这样:
double d5 = 5.0;
q.Append(d5);
有没有什么好方法能够避免临时变量d5?
写回答
1回答
-
quickzhao
2022-12-12
问题1: 这里没必要使用指针类型来定义sum和mean,这二者本身使用值类型就可以完成计算操作,这样不需要出现new;
问题2: 析构函数不仅仅是处理堆空间释放的问题,它可能包括系统中的文件句柄,数据库连接池等资源释放,所以一般来说析构函数是需要定义的;
问题3: 对于你这里的Append操作,它仅仅是添加一个double类型的值,其实不需要使用引用就可以;引用多数是在自定义的class对象中,用以节省空间而用。
022022-12-12
相似问题