c++中设计可以统计自身对象的类(1)

  前天去滑雪,摔的惨不忍睹,腰酸背疼。休息了一天终于缓过劲儿来,把以前落下的功课补上吧。之前找软件方面的工作时经常被问到的一个问题:如何设计一个类,可以统计自身的对象,以及由它派生的对象的个数。当时胡乱说了一通,但是好像很多关键的地方没有注意。经过学习先写一下基本的思路,可能后续还会再写一篇用来完善。

  首先设计一个可以统计自身对象个数的类,初步构想有这么几个特点:

    1、包含一个静态变量作为储存当前对象的计数器;

    2、在构造函数中对计数器作自加操作(包含拷贝构造函数),在虚构函数中对计数器作自减操作

    3、拷贝构造函数实现深拷贝(内容拷贝),防止两个对象公用一块内存,因其中一个对象被析构后令一个对象也被删除(防止统计不准确,事实上很对时候统计不准确都与指针有很大关系)

  根据以上特点我们设计如下类:

class cacu_self_num
{
private:
    static size_t num;
    //static const size_t max_num = 5;
    //其他数据成员
public:
    cacu_self_num();
    cacu_self_num(cacu_self_num&);
    ~cacu_self_num();
    static size_t get_object_num();
    static void init();
protected:
    static void add();
    static void min();
    //static void set_max_num(size_t max);

};

  其实现如下:

#include"classLibrary.h"
#include <iostream>

//begin of defineing cacu_self_num class
size_t cacu_self_num::num = 0;
//const size_t cacu_self_num::max_num = 5;
cacu_self_num::cacu_self_num()
{
    ++num;
    //if(num>max_num)throw "实例化对象达到最大个数"; 
}

cacu_self_num::cacu_self_num(cacu_self_num&)//拷贝构造函数
{
    ++num;
    //if(num>max_num)throw "实例化对象达到最大个数";
}

cacu_self_num::~cacu_self_num()
{
    --num;
}

size_t cacu_self_num::get_object_num()
{
    return num;
}

void cacu_self_num::init()
{
    num = 0;
}

void cacu_self_num::add()
{
    ++num;
}

void cacu_self_num::min()
{
    --num;
}
//end of defining cacu_self_num class

  代码量比较少应该可以看懂,值得注意的是上面的第一条语句:

size_t cacu_self_num::num = 0;

  这条语句将静态成员num的值初始化为零。请注意,不能再类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但是并不分配内存。对于静态变量来说,可以在类声明之外使用单独的语句来进行初始化,这是因为静态类成员变量时单独储存并由该类所有对象共享的,不是对象的组成部分。请注意,初始化语句指出了类型,并使用了作用域运算符,但是没有使用关键字static。初始化是放在方法文件中的而不是头文件,这样可以避免头文件被多次引用时多次初始化,从而引发错误。

  最后来测试一下:

#include "classLibrary.h"
#include<iostream>
using namespace std;

void test_of_static(void)
{
    static int a = 0;//声明初始化语句只会执行一次
    ++a;
    cout<<a<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
    int counter = 0;

    cacu_self_num::init();

    cacu_self_num* a = new cacu_self_num();//此处发现问题,如果写成for循环的形式,那么重复分配给一个指针空间,那么之前
    cout<<a->get_object_num()<<endl;       //分配的空间没有被回收,造成内存泄露
    cacu_self_num* b = new cacu_self_num();
    cout<<b->get_object_num()<<endl;
    
    //print_self_class* c = new print_self_class();
    //cout<<b->get_object_num()<<endl;

    delete a;
    cout<<a->get_object_num()<<endl;
    delete b;
    cout<<b->get_object_num()<<endl;
    //delete c;
    //cout<<c->get_object_num()<<endl;
    


    cin>>counter;
    return 0;
}

  测试过程中发现了一个问题,如果将不同的初始化对象多次赋给一个对象指针,那么之前的对象变成内存垃圾,无法删除,造成内存泄露,目前还没找到解决方法。下一步学习便是解决该问题,并实现派生出来的该类也可以统计自身的个数(分开统计与总计都需要),并设置能够实例化对象的最大个数,并且实现精确统计。初步的简单类就先写到这里,且听下回分解!

转载于:https://www.cnblogs.com/haloworld/p/5042393.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值