C++ SMMA项目继承问题:Campaign无法正确显示继承的Client属性
C++继承类父类属性未正确赋值与显示的问题解决
问题背景
开发SMMA相关C++项目,Campaign类继承自Client类,但运行时输入Campaign对象后,其继承自Client的属性始终显示默认值(NULL/0),且输出时仅显示Campaign自身信息,未包含父类内容。
核心原因
Campaign的输入运算符仅处理自身属性,未触发父类Client的输入逻辑,导致父类成员未被赋值Campaign的输出运算符仅打印自身数据,未输出父类Client的内容- 输入缓冲区残留的换行符导致后续
getline读取异常
解决方案
1. 修改Campaign的输入运算符,先填充父类属性
在Campaign的operator>>中,先调用父类的输入逻辑,再处理自身属性,同时修复输入缓冲区问题:
#include <limits> // 需要添加这个头文件处理ignore istream& operator>>(istream& in, Campaign &obj) { // 先输入Client部分的属性 in >> static_cast<Client&>(obj); // 忽略之前输入留下的换行符,避免getline读取空行 in.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Campaign name: "; char name[100]; in.getline(name, 100); if(obj.campaign_name != nullptr) { delete[] obj.campaign_name; obj.campaign_name = nullptr; } obj.campaign_name = new char[strlen(name) + 1]; strcpy(obj.campaign_name, name); cout << "Objectives (enter each on new line, press Enter to finish): "; string temp; obj.objectives.clear(); // 清空原有内容 while(getline(in, temp)) { if (temp.empty()) { break; } obj.objectives.push_back(temp); cout << "Enter another objective (or press Enter to finish): "; } cout << "Social media platform: "; getline(in, obj.socialMediaPlatform); // 用getline支持带空格的平台名称 return in; }
2. 修改Campaign的输出运算符,包含父类内容
在Campaign的operator<<中,先输出父类Client的信息,再打印自身专属数据:
ostream& operator<<(ostream& out, const Campaign& obj) { // 先输出Client的完整信息 out << static_cast<const Client&>(obj); // 输出Campaign自身信息 out << "---------------------------------------------------" << endl; out << "Campaign name: " << obj.campaign_name << "\n"; out << "Objectives: "; if (!obj.objectives.empty()) { out << "\n"; for (const auto& item : obj.objectives) { out << " -" << item << "\n"; } } else { out << "None\n"; } out << "Social media platform: " << obj.socialMediaPlatform << "\n"; out << "---------------------------------------------------" << endl; return out; }
3. 修正Campaign构造函数的父类初始化
显式调用Client的构造函数,确保父类成员正确初始化:
Campaign::Campaign() : Client() { this->campaign_name = new char[strlen("NULL") + 1]; strcpy(this->campaign_name, "NULL"); this->objectives = {}; this->socialMediaPlatform = "NULL"; }; // 添加支持父类属性的构造函数 Campaign::Campaign(const char* client_name, const string company, const long marketing_budget, const bool contract, const char* campaign_name, const vector<string> objectives, const string socialMediaPlatform) : Client(client_name, company, marketing_budget, contract) { this->campaign_name = new char[strlen(campaign_name) + 1]; strcpy(this->campaign_name, campaign_name); this->objectives = objectives; this->socialMediaPlatform = socialMediaPlatform; }
4. 调整main函数(可选)
如果需要直接输入完整的Campaign对象,无需单独创建Client对象,main函数可简化为:
int main() { Campaign B; cin >> B; cout << B; return 0; }
若要复用已有的Client对象属性,可添加赋值操作:
int main() { Client A; cin >> A; Campaign B; B = A; // 复制Client属性 cin >> B; // 补充Campaign属性 cout << B; return 0; }
修改后效果
运行程序时,会依次提示输入Client和Campaign的所有属性,输出Campaign对象时会同时显示父类Client的完整信息(ClientID、名称、公司等)和自身的专属数据(活动名称、目标、平台)。
内容的提问来源于stack exchange,提问作者Andrei Rusu
相关产品推荐
相关产品推荐

