You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++循环创建对象疑问:对象是否相同及析构必要性

问题分析与解答

先把你的代码整理出来方便后续分析:

// Queue类相关方法
void Queue::testMethod(){ 
    this->theQueue.clear(); 
    for (int i = 0; i < 3 ; i ++ ){ 
        char *uu = new char[3]; 
        uu[0] = 'd'; 
        uu[1] = static_cast<char>(i); 
        uu[2] = 'r'; 
        MyClass tt(uu, 7); 
        this->theQueue.push_back(tt); 
    } 
}

string Queue::PrintData(){ 
    string data; 
    for ( int i = 0 ; i < this->theQueue.size(); i ++){ 
        data += this->theQueue.at(i).PrintData(); 
    } 
    return data; 
}

// MyClass类相关方法
string MyClass::PrintData(){ 
    string data; 
    data += string(this->AM); 
    data += " "; 
    data += this->Number; // 此处存在类型转换错误
    return data; 
}

MyClass::MyClass(char *am, int number) //Constructor 
{ 
    int i = strlen(am); 
    AM = new char[i+1]; 
    strcpy(AM,am); 
    Number = number; 
}

// 主函数
int main() {
    MyClass myClass1((char *)"1111", 3); 
    MyClass myClass2((char *)"1111", 3); 
    MyClass myClass3((char *)"2222", 3); 
    vector<MyClass> tmpVector; 
    tmpVector.push_back(myClass1); 
    tmpVector.push_back(myClass2); 
    tmpVector.push_back(myClass3); 
    Queue tmpQueue(tmpVector); 
    tmpQueue.testMethod(); 
    cout << tmpQueue.PrintData() << endl;
}

执行后输出为 d dr dr,现在逐个解答你的问题:

1. testMethod中的tt对象是否相同?

当然不相同。每次循环迭代里的tt都是栈上的局部自动变量,它的生命周期只限于当前循环体。每次循环都会在栈上分配新的内存空间来存储这个对象,所以每个tt都是独立的实例,内存地址完全不同,自然不是同一个对象。

2. 是否需要在每次迭代中执行析构?

不需要手动调用析构函数——tt作为局部变量,当每次循环迭代结束时,它的生命周期会自动终止,C++会自动调用它的析构函数完成清理。不过这里要提醒你:你的MyClass没有自定义析构函数,默认析构不会释放AM指向的堆内存,会导致内存泄漏。你应该给MyClass补充析构函数:

MyClass::~MyClass() {
    delete[] AM;
}

另外,把ttpush到vector时会触发默认拷贝构造(浅拷贝),这会导致多个MyClass对象共享同一个AM指针,后续析构时会出现重复释放内存的未定义行为,所以你还需要实现拷贝构造函数和拷贝赋值运算符(遵循C++的三/五法则),或者改用智能指针管理内存。

3. 为何会得到d dr dr的输出?

这个输出是由几个代码细节问题共同导致的:

(1)i=0时,uu数组包含字符串结束符'\0'

当i=0时,static_cast<char>(0)就是字符串结束符'\0',此时uu数组内容为{'d', '\0', 'r'}。MyClass构造函数里用strlen(am)计算长度,而strlen会读到'\0'就停止,所以strlen(uu)返回1,你给AM分配了2个字符的内存,strcpy只会把'd'和'\0'拷贝进去。后续PrintData用string(this->AM)转换时,遇到'\0'就截断,所以第一个元素的有效字符串是d。

(2)i=1和i=2时,uu数组缺少结束符,且包含不可打印字符

你创建的uu是new char[3],只赋值了三个元素但没有加'\0',strlen(uu)会越界读取内存直到找到'\0',这属于未定义行为,但在你的环境中刚好读取到了结束符,所以AM被分配了足够内存,拷贝了{'d', char(1), 'r', '\0'}(或char(2))。其中char(1)和char(2)是不可打印的控制字符,输出时不会显示,所以看起来有效字符串是dr。

(3)PrintData方法的类型转换错误

你直接把int类型的Number加到string里,会把数字7转换成对应的ASCII控制字符(响铃符,不可打印),所以输出里看不到数字,最终拼接后就成了d dr dr。正确的写法应该用to_string(this->Number)来转换数字。


内容的提问来源于stack exchange,提问作者Konstantinosdms

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:03:09