64,643
社区成员
发帖
与我相关
我的任务
分享
// fg.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<string>
#include<iostream>
using namespace std;
template<class T>
class share
{
public:
share():point(0),pcount(NULL){}
share(T* p1)
{
pcount=new int(0);
point = p1;
if (pcount == NULL)
{
pcount = new int(1);
}
}
~share()
{
if(--(*pcount) == 0)
{
delete point;
delete pcount;
pcount = NULL;
cout << "begin to delete share" << endl;
point = NULL;
}
}
share(share& t2)
{
point = t2.point;
(*t2.pcount)++;
pcount = t2.pcount;
}
share& operator =(share& t2)
{
if (--(*pcount) == 0)
{
delete point;
}
point = t2.point;
t2.(*pcount)++;
cout<<t2.(*pcount)<<endl;
cout<<*(t2.pcount)<<endl;
pcount = t2.pcount;
return *this;
}
T* operator ->()
{
return point;
}
private:
T* point;
int* pcount; //应该用boost::detail::atomic_count
};
class A
{
public:
A()
{
n = 0;
}
int n;
char v[4];
};
int main()
{
share<A> sp(new(std::nothrow) A());
sp->n = 10;
cout << "sp->n is :" << sp->n << endl;
share<A> sp2 = sp;
sp2->n = 20;
cout << "sp->n is :" << sp2->n << endl;
return 0;
}
share():point(0),pcount( new int(0)){}
这种方式初始化,但是pcount每次都初始化失败,为空的。另外在析构函数这里 ~share()
{
if(--(*pcount) == 0)
{
delete point;
delete pcount;
pcount = NULL;
cout << "begin to delete share" << endl;
point = NULL;
}
}
这样就会奔溃,程序已经执行完了,明显是内存泄漏奔溃,但是把单步后定位在 if(--(*pcount) == 0)
把 if(--(*pcount) == 0)
改成 if((*pcount) == 0)
这样就不会奔溃,纳闷了,假如不--,下面的就没办法执行,就没有释放,程序就不奔溃。。。
~share()
{
if((*pcount) == 0)
{
delete point;
delete pcount;
pcount = NULL;
cout << "begin to delete share" << endl;
point = NULL;
}
else
{
--pcount;
}
}
~share()
{
if((*pcount) == 0)
{
delete point;
delete pcount;
pcount = NULL;
cout << "begin to delete share" << endl;
point = NULL;
}
else
{
---(*pcount);
}
}
问题解决了,我知道问题所在了,我没判断就先--了,其实我的shaer
这个是错的,其实我也不知道为啥编译器不报错,所以我留着。。。// 改了一下, 说几点:
// 1. 使用c++11的一些特性, 初学者一开始就学好
// 2. 使用类的构造初始化列表构造对象是一个好习惯
// 3. 复制构造函数的参数是const T&, 不要忘了
// 4. 既然提供了默认构造函数使指针为空, 为什么在析构函数里面以至其他函数都不判断一下?
// 5. c++允许手动调用析构/构造函数, 让operator=写法便利了不少
// 6. 既然知道有std::nothrow 那一步判断是否指针为空不明所以
// 7. 注释上写了最好使用原子操作, 为什么不写进模板参数, 这样我单线程使用就不用原子操作了
#include <string>
#include <iostream>
template<class T, class U> class share
{
public:
share() :point(nullptr), pcount(nullptr) {}
share(T* p) : point(p), pcount(new U(1)) { }
~share() {
if (!this->pcount) return;
if (!--(*pcount)) {
delete point;
delete pcount;
//cout << "begin to delete share" << endl;
}
}
share(const share& t2) noexcept : point(t2.point), pcount(t2.pcount) {
if (this->pcount) (*this->pcount)++;
}
share(share&& t2) noexcept : point(t2.point), pcount(t2.pcount) {
t2.point = nullptr;
t2.pcount = nullptr;
}
share& operator =(share&& t2) noexcept {
this->share::~share();
this->share::share(std::move(t2));
return *this;
}
share& operator =(const share& t2) noexcept {
this->share::~share();
this->share::share(t2);
return *this;
}
T* operator ->() noexcept { return point; }
private:
T* point;
U* pcount;
};
class A
{
public:
A()
{
n = 0;
}
int n;
char v[4];
};
int main()
{
share<A, int> sp(new(std::nothrow) A());
sp->n = 10;
std::cout << "sp->n is :" << sp->n << std::endl;
share<A, int> sp2 = sp;
sp2->n = 20;
std::cout << "sp->n is :" << sp2->n << std::endl;
return 0;
}