计算2个不同类的创建对象会导致问题

时间:2017-04-26 13:43:40

标签: c++ class templates constructor

我想计算创建的对象。如果我用一个类来做这件事很容易,但我想要来自2个不同类的计数对象,其中2个不同的计数器相互交互。 简化示例:

template <class Obj>
class Counter1
{
    private: 
        static int total1;
    public:
        Counter1(){++total1;}
        .. destuctor, copy constructor ..
       static int getCounter1() {return total1;}
       static void setCounter1(int var) {total1 = var;}
};
template<class Obj> int Counter1<Obj>::total1(0);

template <class Obj>
class Counter2
{
    private: 
        static int total2;
    public:
        Counter2(){++total2;}
        .. destuctor, copy constructor ..
       static int getCounter2() {return total2;}
       static void setCounter2(int var) {total2 = var;}
};
template<class Obj> int Counter2<Obj>::total2(0);

class Test1 : private Counter1<Test1>
{
 .. some code ..
};
Test1::Test1() : Counter1()
{
   int tmp_var;
   tmp_var = Counter2<int>::getCounter2();
}

可悲的是tmp_var永远不会得到有效的号码。或者换句话说,它保持在零并且不会增加。我究竟做错了什么?

_________________ EDIT__________________
这是一个更详细的例子:

template <class Obj>
class Counter1
{
    private:
        static int total1;

    public:
        Counter1() {++total1;}
        Counter1(const Counter1& countObj) {if(this != &countObj) {++total1;}}
        ~Counter1() {--total1;}

        static int getCounter1() {return total1;}
        static void setCounter1(int var){total1 = var;}
};
template <class Obj> int Counter1<Obj>::total1(0);

template <class Obj>
class Counter2
{
    private:
        static int total2;

    public:
        Counter2() {++total2;}
        Counter2(const Counter2& countObj) {if(this != &countObj) {++total2;}}
        ~Counter2() {--total2;}

        static int getCounter2() {return total2;}
        static void setCounter2(int var){total2 = var;}
};
template <class Obj> int Counter2<Obj>::total2(0);

/* Memory are with a static Size with variable object Size allocator */
class Class1 : private Counter2<Class1>
{
    public:
        Class1();

        .. some methods ..

    private:
       .. some members ..
    };

/* Constructor */
Class1::Class1() : Counter2()
{
    const int varTotal1 = Counter1<int>::getCounter1();
    const int varTotal2 = getCounter2()-1;

    .. some code ..
}

.. some methods ..

class Class2 : private Counter1<Class2>
{
    public:
        Class1 _PoolsObj[TASKS_PER_PROCESS];

        Class2();
};

Class2::Class2() : Counter1()
{
    _PoolsObj[TASKS_PER_PROCESS] = {};

    /* Reset the task counter */
    Counter2<int>::setCounter2(0);
}

static Class2 class_pool[64];

我有两个问题:
1)Counter2<int>::setCounter2(0);不起作用
2)const int varTotal1 = Counter1<int>::getCounter1();始终为0

2 个答案:

答案 0 :(得分:1)

根据您的新样本,以下是我的意见。 首先,不要忘记模板的每个实例都有自己的静态变量。它不像其他标准类。这就是你的伎俩。

原因

const int varTotal1 = Counter1<int>::getCounter1();

始终为0是模板counter1的实例由class2继承。但是你要求来自class1的counter1的getCounter1()给你计数或total1的值。 Class1不了解getCounter1()。请注意,在示例代码中使用以下代码行实例化类时,counter1的total1在实例化Class2时正确递增,而Class2知道getCounter1(),如果碰巧在Class2中包含getCounter1(),则可以看到total1值。

static Class2 class_pool[64];

至于以下代码,据我所知,它可行。

Counter2<int>::setCounter2(0);

作为最后一点,如果我是你,我将只有一个模板说反击。像往常一样使用它来控制每个类的已创建对象的计数。如果要查看来自另一个类的一个类的计数,为什么不创建第三个实用程序共享类,您可以在其中存储对象的计数。或者你可以使用mixin根据需要组合类(使用继承和组合),但这可能是一种矫枉过正。

顺便说一下,你的代码不完整,你错过了定义

 TASKS_PER_PROCESS  in 
  _PoolsObj[TASKS_PER_PROCESS] = {};
   I added the following to just compile your code ..
   #define TASKS_PER_PROCESS 10

答案 1 :(得分:0)

我想通了,我做错了什么,并做了一些重大改进。

1)感谢@ tobi303的评论,我可以删除一个计数器,只使用一个计数器用于不同的对象。

2)我的代码中有一个语义错误。 _PoolsObj[TASKS_PER_PROCESS] = {};完全错了。我想用0来初始化所有数组元素,但这只是第五次调用构造函数并将第四个(TASK_PER_PROCESS)元素设置为0.我现在在变量声明之后放置初始化列表以确保正确创建。

3)

public:
        Class1 _PoolsObj[TASKS_PER_PROCESS];

这当然不是很好的方式,所以我包含了一个getter函数并将数组设置为private。

4)我的问题是由这两行代码引起的:

Counter1<int>::getCounter1();
Counter2<int>::setCounter2(0); 

类型不应该是int,它应该是类名:

Counter1<Class2>::getCounter();
Counter2<Class1>::setCounter(0); 

我想我设置并获得了一个int的计数器而不是我的类。

这里我的固定代码只是为了完成:

template <class Obj>
class Counter
{
    private:
        static int total;

    public:
        Counter() {++total;}
        Counter(const Counter& countObj) {if(this != &countObj) {++total;}}
        ~Counter() {--total;}

        static int getCounter() {return total;}
        static void setCounter(int var){total = var;}
};
template <class Obj> int Counter<Obj>::total(0);

class Class1 : private Counter<Class1>
{
    private:
        int member;

    public:
        int getMember();
        Class1();
};

class Class2 : private Counter<Class2>
{
    private:
        Class1 _PoolsObj[TASKS_PER_PROCESS] = {};
    public:
        Class1 getPool(int index);
        Class2();
};

Class1::Class1()
{
    const int varTotal1 = Counter<Class2>::getCounter()-1;
    const int varTotal2 = getCounter()-1;

    std::cout<<"varTotal1: "<<varTotal1<<std::endl;
    std::cout<<"varTotal2: "<<varTotal2<<std::endl;
}

int Class1::getMember()
{
    return member;
}


Class2::Class2()
{
    std::cout<<"Class2 Constructor"<<std::endl<<std::endl;

    /* Reset the task counter */
    Counter<Class1>::setCounter(0);
}

Class1 Class2::getPool(int index)
{
    return _PoolsObj[index];
}

static Class2 class_pool[64];