#include
#include
#include
using namespace std;
class Person {
public:
Person() {
cout <<"Pserson()"<()
{
return p;
}
};
void test_func(void)
{
sp i1(5);
sp i2 = 6;
sp s = new Person();
sp s3(new Person) ;
s3->printInfo();
}
int main(int argc, char **argv)
{
test_func();
return 0;
}
初始化变量两种方法:
第一种方法:
class sp;
int k=2;
sp i1(k); //定义sp对象i1,并传入int类型,初始化参数,将调用 sp(int i) 。
第二种方法:
sp i2 = k; ///定义sp对象i2,并传入int类型的k变量,初始化参数,将调用 sp(int i) 。
说明:
sp s3(new Person) ;
s3->printInfo();
s3中没有printInfo函数,但是sp对象重载了->符号,返回了sp中person类型的私有数据p的指针tmp,指针再调用printInfo函数。
void test_func(void)
{
Person *p = new Person();
per.printInfo();
}
int main(int argc, char **argv)
{
int i;
for (i = 0; i < 2; i++)
test_func();
return 0;
}
在 test_func中,使用new Person开辟的内存,没有释放,没有执行Person类的析构函数。
在test_func中,使用局部变量,执行Person类的析构函数。
void test_func(void)
{
Person per;
per.printInfo();
}
int main(int argc, char **argv)
{
int i;
for (i = 0; i < 2; i++)
test_func();
return 0;
}
如果
如果函数test_func,是person类指针,则可以在函数test_func申请一个sp类变量A,在sp类中包含person类指针,在释放sp类的析构函数中,如果sp类中的person类指针被赋值,则删除person类指针指向的内存。
class sp {
private:
Person *p;
public:
sp() : p(0) {}
sp(Person *other)
{
cout<<"sp(const Person *other)"<()
{
return p;
}
};
void test_func(sp &other)
{
sp s = other;
s->printInfo();
}
int main(int argc, char **argv)
{
sp other = new Person();
test_func(other);
cout<<"main() end"<
说明:
修改3:析构函数修改为const sp &,修改代码如下:
class sp {
sp(const sp &other)
{
cout<<"sp(const Person *other)"<
问题:二次删除指针。
43 ~sp()
44 {
45 cout<<"~sp()"<printInfo();
67 }
68
69 int main(int argc, char **argv)
70 {
71
72 sp other = new Person();
73 test_func(other);
74
75 cout<<"main() end"<
在test_func执行结束时候,销毁other,执行sp类析构函数,判断p不为空,则delete p指向的p1;在main函数执行结束后,销毁s1,显然p=123456,不为空,再次销毁p,会产生错误。
解决思路:引入计数,当是最后一个使用者,销毁p。
解决程序如下:
8 class Person {
9 private:
10 int count;
11
12 public:
13 void incStrong(){ count++; }
14 void decStrong(){ count--; }
15 int getStrongCount(){ return count;}
16
17 Person() : count(0){
18 cout <<"Pserson()"<incStrong();
51 }
52
53 ~sp()
54 {
55 cout<<"~sp()"<decStrong();
60 //cout<<"~sp() delete1"<getStrongCount<
计数count很多类中都用,把count封装成一个基类。
class RefBase {
private:
int count;
public:
RefBase() : count(0) {}
void incStrong(){ count++; }
void decStrong(){ count--; }
int getStrongCount(){ return count;}
};
class Person : public RefBase{
public:
Person() {
cout <<"Pserson()"<
有用信息是,SP类属性P指针,P既可以是person类,也可以是其他类。把SP类做成模板。代码如下:
template
class sp {
private:
T *p;
public:
sp() : p(0) {}
sp(T *other)
{
cout<<"sp(T *other)"<incStrong();
}
sp(const sp &other)
{
cout<<"sp(const sp &other)"<incStrong();
}
~sp()
{
cout<<"~sp()"<decStrong();
if (p->getStrongCount() == 0)
{
delete p;
p = NULL;
}
}
}
T *operator->()
{
return p;
}
T& operator*()
{
return *p;
}
};
如图所示,两个线程操作cout,如果在A线程的count还没写进内存,B线程从内存取的count不是A线程增加过的,就会导致count=2,而不是3.解决办法,最count进行原子操作。
163 template
164 class LightRefBase
165 {
166 public:
167 inline LightRefBase() : mCount(0) { }
168 inline void incStrong(__attribute__((unused)) const void* id) const {
169 __sync_fetch_and_add(&mCount, 1);
170 }
171 inline void decStrong(__attribute__((unused)) const void* id) const {
172 if (__sync_fetch_and_sub(&mCount, 1) == 1) {
173 delete static_cast(this);
174 }
175 }
在Android引入,__sync_fetch_and_add(&mCount, 1)对count进行原子操作。