【问题标题】:Counting number of objects of different classes计算不同类别的对象数量
【发布时间】:2018-02-15 18:02:12
【问题描述】:

我想计算我的程序在其生命周期内创建的对象数量。基于此处提供的解决方案:

how to count the number of objects created in c++

我有以下代码:

#include <iostream>
using namespace::std;
using std::cout;
using std::endl;

template <typename T>
struct counter
{
    counter()
    {
        objects_created++;
        objects_alive++;
    }

    virtual ~counter()
    {
        --objects_alive;
    }
    static int objects_created;
    static int objects_alive;
};
template <typename T> int counter<T>::objects_created(0);
template <typename T> int counter<T>::objects_alive(0);

class X : counter<X>
{
    int a;
};

class Y : counter<Y>
{
    int b;
};

void fooX(class X x) {
    cout << "passing object" << endl;
}

void fooY(class Y& y) {
    cout << "passing reference" << endl;
}

int main()
{
    cout << "created: " << " X:" << counter<X>::objects_created << " Y:" << counter<Y>::objects_created << endl;
    cout << "alive: " << " X:" << counter<X>::objects_alive << " Y:" << counter<Y>::objects_alive << endl;
    X x;
    Y y;
    cout << "created: " << " X:" << counter<X>::objects_created << " Y:" << counter<Y>::objects_created << endl;
    cout << "alive: " << " X:" << counter<X>::objects_alive << " Y:" << counter<Y>::objects_alive << endl;
    fooX(x);
    fooY(y);
    cout << "created: " << " X:" << counter<X>::objects_created << " Y:" << counter<Y>::objects_created << endl;
    cout << "alive: " << " X:" << counter<X>::objects_alive << " Y:" << counter<Y>::objects_alive << endl;
    int ui;
    cin >> ui;
}

我预计由于 x 是按值传递的,因此会在 fooX 内部制作一个副本,使 class X 的对象总数为 2,而由于 y 是按引用传递的,总数class Y 的对象数为 1。

然而,代码的输出如下:

created:  X:0 Y:0
alive:  X:0 Y:0
created:  X:1 Y:1
alive:  X:1 Y:1
passing object
passing reference
created:  X:1 Y:1
alive:  X:0 Y:1

为什么Xs创建的数量不是2?

【问题讨论】:

  • 你忘记了基类中的复制构造函数:counter(T const &amp;)
  • @RichardCritten 我当时的错误理解是,如果用户不提供,编译器会自动提供。让我试试你的建议。
  • 编译器确实提供了一个,但它可能做不到你想要的。
  • 默认的复制构造函数实在是太笨了。复制数据成员的工作是绝对最少的(导致指针和其他需要特殊处理的资源非常有趣。有关更多信息,请参阅What Is the Rule Of Three?),仅此而已。它不会增加计数器,也不会通过去收集 200 美元。
  • 还简洁明了 operator= 的 LHS 对象中的计数器会发生什么并且不要忘记复制省略:en.cppreference.com/w/cpp/language/copy_elision

标签: c++ pass-by-reference pass-by-value


【解决方案1】:

复制构造函数会自动添加到您的 counter 类中,并且自动创建的复制构造函数不会增加您的静态变量。

编写一个复制构造函数:

counter(counter const&)
{
    objects_created++;
    objects_alive++;
}

请注意,您的析构函数可能不应该是virtual,除非您打算通过指针或对counter 的引用来删除动态创建的派生类实例。就目前而言,这只是过早的悲观,因为它不必要地增加了对象的大小。

【讨论】:

  • 我在上面的代码中添加了counter(T const &amp; t) {objects_created++;objects_alive++;} 并重新运行,它仍然给了我在 OP 中指出的相同结果。也就是说,X 创建的对象数量仍然显示为 1 而不是 2。
  • @Tryer:那是因为counter(T const &amp; t) 不是复制构造函数。它只是一个普通的构造函数,采用T,如counter(int number)counter(std::string const&amp; text)
  • 是的。我将其更改为您在答案中的代码并且它有效。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2015-06-14
  • 1970-01-01
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
相关资源
最近更新 更多