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

调用C++带参数构造函数失败,默认构造函数被误触发

构造函数调用异常:带参构造未执行,默认构造被触发

问题说明

  • 需求:
    • 默认构造函数:从指定TXT文件读取单词,存入fileVec向量
    • 带参构造函数:从传入的字符串中读取单词,添加至fileVec向量
  • 问题:main函数中尝试调用带参构造函数时,实际执行的是默认构造函数,预期逻辑未生效

原代码

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;

class stringSet
{
private:
    int i = 0;
    string fileName, line, word, word2;
    istringstream iss;
    fstream file;
    vector<string> fileVec;

public:
    string str = "that's a string for parameterized constructor";

    stringSet()
    {
        cout << "Please enter filename: ";
        getline(std::cin, fileName);
        fileName += ".txt";
        file.open(fileName, ios::in);
        if (file.is_open())
        {
            while (getline(file, line))
            {
                iss.clear();
                iss.str(line);
                while (iss.good())
                {
                    iss >> word;
                    fileVec.push_back(word);
                    cout << fileVec[i] << endl;
                    i++;
                }
            }
        }
    }
    
    stringSet(string str)
    {
        istringstream iss2(str);
        while (iss2 >> word2)
            fileVec.push_back(word2);
        cout << fileVec[i] << endl;
        i++;
    }
};

int main()
{
    // stringSet();
    stringSet(str);
    return 0;
}

问题根源

  1. 对象创建语法错误:stringSet(str);会被C++编译器解析为函数声明——声明一个名为str的无参函数,返回值类型为stringSet,而非调用带参构造函数创建对象。
  2. 变量作用域错误:main函数中直接使用str是无效的,str是stringSet类的非静态成员,必须通过类对象访问,或在main中独立定义该字符串变量。
  3. 带参构造函数潜在问题:依赖成员变量i输出内容,初始时i=0能正常输出第一个元素,但后续逻辑中i的管理容易出错。

修复方案

1. 修正对象创建方式

在main中定义参数字符串,用正确的语法创建带参构造的对象:

int main()
{
    // 定义参数字符串
    string input_str = "that's a string for parameterized constructor";
    // 正确调用带参构造函数
    stringSet obj(input_str);
    return 0;
}

2. 优化带参构造函数

使用const引用避免字符串拷贝,直接输出读取的单词,减少对成员变量i的依赖:

stringSet(const string& str)
{
    istringstream iss2(str);
    string word;
    while (iss2 >> word)
    {
        fileVec.push_back(word);
        cout << word << endl;
    }
}

3. 可选:使用类静态成员传递参数

如果要复用类内的字符串,可将str改为静态成员:

class stringSet
{
public:
    static string str; // 声明静态成员
    // ... 其他代码
};

// 类外初始化静态成员
string stringSet::str = "that's a string for parameterized constructor";

此时main中调用方式为:

stringSet obj(stringSet::str);

完整修复代码

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;

class stringSet
{
private:
    int i = 0;
    string fileName, line, word;
    istringstream iss;
    fstream file;
    vector<string> fileVec;

public:
    // 默认构造:读取TXT文件
    stringSet()
    {
        cout << "Please enter filename: ";
        getline(std::cin, fileName);
        fileName += ".txt";
        file.open(fileName, ios::in);
        if (file.is_open())
        {
            while (getline(file, line))
            {
                iss.clear();
                iss.str(line);
                while (iss >> word)
                {
                    fileVec.push_back(word);
                    cout << fileVec[i] << endl;
                    i++;
                }
            }
            file.close(); // 关闭文件,避免资源泄漏
        }
        else
        {
            cout << "Failed to open target file!" << endl;
        }
    }
    
    // 带参构造:读取字符串
    stringSet(const string& str)
    {
        istringstream iss2(str);
        while (iss2 >> word)
        {
            fileVec.push_back(word);
            cout << word << endl;
        }
    }
};

int main()
{
    string input_str = "that's a string for parameterized constructor";
    stringSet obj(input_str);
    // 若需调用默认构造,使用:stringSet obj_default;
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:10:18