繁体   English   中英

使用构造函数和析构函数的 C++ 中的对象计数器

[英]Object counter in C++ using Constructor and Destructor

所以,我是新来的,如果我犯了任何错误,请多多包涵。

我是一名正在学习 C++ 的大学生,并且是构造函数和析构函数的新手。

我想要做的是:我需要创建一个程序来维护对象的实时计数,即,无论何时创建或销毁该类的对象,对象计数器都会分别递增/递减并显示(这是我的逻辑无论如何,建议会让我感激不尽)。

这意味着创建一个静态变量,我做了这个:

class objectCount
{
    protected:
    static int count;

    public:
    objectCount()
    {
        count++;
        cout<<"Object of type class created. \nNo. of objects of type class currently: "<<count<<endl;
    }

    ~objectCount()
    {
        count--;
        cout<<"Latest object of type class deleted. \nNo. of objects of type class currently: "<<count<<endl;
    }
};

int objectCount::count=0;

void main()
{
    int ch;
    clrscr();
    cout<<"--------------- || OBJECT COUNTER || ----------------"<<endl;

    do {
        cout<<"1. Create Object\n2. Delete Object\n3.Exit";
        cout<<endl<<"Enter your choice: ";
        cin>>ch;

        switch(ch)
        {
            case 1: objectCount();
                break;

            case 2: ~objectCount();
                break;

            case 3: break;

            default: cout<<endl<<"Invalid Choice.";
                break;
        };
    }while(ch!=3);
    getch();
}

所以,我以为我已经准备好了,准备好了,但是 TurboC(是的,我的大学强迫我们使用 TC,因此我别无选择,只能使用它)给了我一个错误(非法结构操作)在“案例 2:~objectCounter();” 部分。 我翻阅了这些书,意识到我忘记了构造函数也需要一个对象声明。 (objectCount OC;)

但是现在我对如何更改代码以使其工作感到困惑。

我需要它以便根据用户的选择创建一个对象,不。 更新和打印的对象,否则删除对象,否。 打印和更新的对象,完成后退出。

我四处搜索,但通常人们发布示例只是声明有限数量的对象,例如“objectCount c1; objectCount c2;” 并完成它,这不是我真正的情况。

你们中的任何人,受人尊敬的,善良的,温柔的和知识渊博的社区可以帮助我吗?

编辑:理想输出:

--------------- || OBJECT COUNTER || ----------------
1. Create Object
2. Delete Object
3. Exit
Enter your choice:  1
Object of type class created. 
No. of objects of type class currently: 1 //Static variable incremented & displayed here.

1. Create Object
2. Delete Object
3. Exit
Enter your choice:  1
Object of type class created. 
No. of objects of type class currently: 2 //Static variable incremented & displayed here.

1. Create Object
2. Delete Object
3. Exit
Enter your choice:  2
Object of type class deleted 
No. of objects of type class currently: 1 //Static variable decremented & displayed here.

1. Create Object
2. Delete Object
3. Exit
Enter your choice:  3

编辑 2 :我想我会按照 besc 的建议使用 100 个对象的数组,现在应该可以使用。

但是感谢大家的回答,是的,我肯定会超越 TC 并学习真正的交易。

欢迎!

~objectCount()的问题本质上是它说“删除 objectCount 对象”......而编译器说“哪个?” 如果您不以某种方式跟踪您创建的对象,您可能正在内存泄漏这些对象。

我建议使用newdelete关键字,而不是直接调用构造函数和析构函数。 那些操作 objectCount 指针,例如,您可以使用以下代码:

objectCount * my_object = new objectCount(); // allocates memory, calls constructor
delete my_object; // calls destructor, frees memory

这就是对单个 objectCount 对象进行内存管理的方法。 为了保留这些对象中的许多,您可能需要维护这些指针的数组或std::vector

您对计数逻辑的实现是正确的(只要您处于单线程场景中),但您的main()则不是。

case 1的切换中,您正在做的是创建一个未命名的临时objectCount对象,该对象立即再次被销毁。 你会看到 ctor 被立即调用,然后是对 dtor 的调用。 为什么会立即销毁? 因为你没有给它起名字。 所以,这不是特别有用,但有效; 虽然这显然不是你想要的。

case 2无法编译,因为您在没有对象的case 2调用了 dtor。 这里实际上有两个问题。

(1) dtor 需要知道它应该销毁哪个objectCount对象。 在这方面,它的作用类似于任何其他非静态成员函数。 这会起作用:

// Creates an object, ctor gets called.
objectCount obj;

// Calls the destructor on obj.
// DO NOT DO THIS! See (2).
obj.~objectCount();  

(2)在 C++ 中,显式调用 dtor 的情况很少。 只要您处于学习 C++ 的早期阶段,它们就无关紧要。 所以这是一个有效的规则:如果你明确地调用一个 dtor,你就做错了。 当一个对象死亡时,Dtors 被隐式调用。 这种死亡是如何发生的取决于你的对象被分配在哪里。

在堆栈上:

void func() {
    objectCount obj;
} // obj goes out of scope here: dtor is called

在堆上:

objectCount* obj = new objectCount;
// ...
delete obj; // dtor is called

只要有可能,就更喜欢堆栈,因为使用 new/delete 手动管理内存非常容易出错。

正如您在堆栈示例中看到的,范围是由花括号定义的。 如果您需要对对象的生命周期进行更细粒度的控制,您可以使用一组“独立”卷曲。 即您的main()可能如下所示:

//...

do {
    cout << "1. Create/destroy on the stack\n"
    cout << "2. Create/destroy on the heap\n
    cout << "3.Exit";
    cout<<endl<<"Enter your choice: ";
    cin>>ch;

    switch(ch)
    {
        case 1: {
            {
                // Note the standalone set of curlies.
                objectCount obj;
            }
            break;
        }

        case 2: {
            objectCount* obj = new objectCount;
            delete obj;
            break;
        }

        case 3: break;

        default: cout<<endl<<"Invalid Choice.";
            break;
    };
}while(ch!=3);

// ...

为了让您的用户选择明确地创建和销毁,您需要在此处使用 new/delete。 没有合适的范围可以提供相同的效果。 但在此之前,请考虑可能出错的事情。 例如,如果用户决定连续创建两次……或连续删除两次,会发生什么。

编辑:

要让用户创建和销毁任意数量的对象,您需要保留一个包含现有对象的列表,即std::vector 那时 TurboC 成为一个真正的问题,因为它早于 C++ 标准模板库 (STL),向量是其中的一部分。 并且此时您不想自己实现 vector。

让我说一下,您的州教育委员会决定将 DOS 时代的 IDE 强加给您,这是多么令人难以置信的脑残。 您不会以这种方式学习任何有用的 C++。 如果您只是为了功劳而使用 C++,请完成它,然后忘记体验。 但是,如果您对该语言完全感兴趣,请为自己准备一个现代编译器和 IDE,并在您自己的时间做一些真正的 C++。 你选择什么并不重要:免费版的 Visual Studio、Clang 或 GCC 与 Qt Creator、Eclipse、CLion:任何东西都将在与 TurboC 完全不同的世界中发挥作用。 [叹气,现在感觉好多了,这已经不在我的胸口了;)]

好的,如何解决您眼前的问题? 让它更简单。 使用 C 风格的固定长度数组,包含指向创建的对象的指针和一个保存当前分配对象数量的变量。

// ... in main() outside the loop ...
// 100 objects should be enough for everybody :)
// DO NOT DO THIS IN REAL C++! Use std::vector instead!
objectCount* object_ptrs[100];
int current_max_idx = 0;

现在您可以使用new / delete来创建和销毁最多 100 个对象,并在此过程中递增和递减current_max_idx 确保在程序退出时delete所有剩余的对象,并记住数组是从零开始的,即object_ptrs索引为 0 到 99。

还可以考虑从 ctor 和 dtor 中删除计数逻辑。 这是多余的,因为current_max_idx变量执行相同的工作,并且在创建/销毁时打印可能发生在switch

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM