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

Object counter in C++ using Constructor and Destructor

本文关键字:析构函数 对象 计数器 构造函数 C++      更新时间:2023-10-16

所以,我是新来的,如果我犯了任何错误,请耐心等待。

我是一名学习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 Objectn2. Delete Objectn3.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,学习真正的交易。

计数逻辑的实现是正确的(只要您停留在单线程场景中),但main()不是。

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

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,你就做错了。当一个对象死亡时,Dtor被隐含地调用。死亡是如何发生的取决于你的对象被分配到哪里。

堆栈上:

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

堆上:

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

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

正如您在堆栈示例中看到的,范围是由大括号定义的。如果您需要对对象的生存期进行更细粒度的控制,可以使用一组"独立"curlies。也就是说,你的main()可能是这样的:

//...
do {
cout << "1. Create/destroy on the stackn"
cout << "2. Create/destroy on the heapn
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),矢量是STL的一部分。在这一点上,您不希望自己实现向量。

让我说一下,你们州教育委员会的决定是多么令人难以置信地愚蠢,迫使你们使用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中可以在创建/销毁时进行打印。

欢迎!

~objectCount()的问题本质上是它说"删除objectCount对象"。。。编译器会说"哪一个?"如果你不以某种方式跟踪你创建的对象,你可能会泄露这些对象的内存。

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

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

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