调用C++带参数构造函数失败,默认构造函数被误触发
构造函数调用异常:带参构造未执行,默认构造被触发
问题说明
- 需求:
- 默认构造函数:从指定TXT文件读取单词,存入
fileVec向量 - 带参构造函数:从传入的字符串中读取单词,添加至
fileVec向量
- 默认构造函数:从指定TXT文件读取单词,存入
- 问题: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; }
问题根源
- 对象创建语法错误:
stringSet(str);会被C++编译器解析为函数声明——声明一个名为str的无参函数,返回值类型为stringSet,而非调用带参构造函数创建对象。 - 变量作用域错误:main函数中直接使用
str是无效的,str是stringSet类的非静态成员,必须通过类对象访问,或在main中独立定义该字符串变量。 - 带参构造函数潜在问题:依赖成员变量
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
相关产品推荐
相关产品推荐

