C++中类项目的继承

3lxsmp7m  于 2023-05-20  发布在  其他
关注(0)|答案(2)|浏览(219)

In the image what is written in black are variables specific for each class and what is blue is inherited from the client class. This is pretty much what I want to do我有一个关于SMMA的C++类项目,其中我有这些类:客户端、活动、分析、发票、发布。注意,我必须使用继承。

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;

class IOinterface{
public:
    virtual istream& input(istream&) = 0;
    virtual ostream& output(ostream&) const = 0;
};

class Client {
    protected:
        char* client_name;
        const int clientID;
        static int numberOfClients;
        string company;
        long marketing_budget;
        bool contract;
    public:
        void setClientName(const char* newClientName) {
            if(this->client_name != nullptr) {
                delete[] this->client_name;
                this->client_name = nullptr;
            }
            this->client_name = new char [strlen(newClientName) + 1];
            strcpy(this->client_name, newClientName);
        }
        const char* getClientName() const {return this-> client_name;}

        void setCompany(string newCompany) {this->company = newCompany;}
        string getCompany() {return this->company;}

        
        void setMarketingBudget(long newMarketingBudget) {this->marketing_budget = newMarketingBudget;}
        long getMarketingBudget() {return this->marketing_budget;}
    

        void setContract(bool newContract) {this->contract = newContract;}
        bool getContract() {return this->contract;}

        Client();
        Client(const char* client_name, const string company, const long marketing_budget, const bool contract);
        Client(const Client& obj);

        Client& operator=(const Client& obj);

        ~Client();

        friend istream& operator>>(istream& in, Client& obj);
        friend ostream& operator<<(ostream& out, const Client& obj);

};

int Client::numberOfClients = 0;

Client::Client():clientID(++numberOfClients){
    this->client_name = new char[strlen("NULL") + 1];
    strcpy(this->client_name, "NULL");
    this->company = "NULL";
    this->marketing_budget = 0;
    this->contract = 0;
}

Client::Client(const char* client_name, const string company, const long marketing_budget, const bool contract):clientID(++numberOfClients) {
    this->client_name = new char[strlen(client_name) + 1];
    strcpy(this->client_name, client_name);
    this->company = company;
    this->marketing_budget = marketing_budget;
    this->contract = contract;
}

Client::Client(const Client& obj):clientID(++numberOfClients) {
    this->client_name = new char[strlen(obj.client_name) + 1];
    strcpy(this->client_name, obj.client_name);
    this->company = obj.company;
    this->marketing_budget = obj.marketing_budget;
    this->contract = obj.contract;
}

Client& Client::operator=(const Client& obj) {
    if(this != &obj) {
        if(this->client_name != nullptr) {
            delete[] this->client_name;
            this->client_name = nullptr;
        }
        this->client_name = new char[strlen(obj.client_name) + 1];
        strcpy(this->client_name, obj.client_name);
        this->company = obj.company;
        this->marketing_budget = obj.marketing_budget;
        this->contract = obj.contract;
    }
    return *this;
}

Client::~Client() {
    if (this->client_name != nullptr) {
        delete[] this->client_name;
        this->client_name = nullptr;
    }
}

istream& operator>>(istream& in, Client& obj) {
    cout << "Client name: ";
    char name[150];
    in.getline(name, 150);
    if (obj.client_name != nullptr) {
        delete[] obj.client_name;
        obj.client_name = nullptr;
    }
    obj.client_name = new char[strlen(name) + 1];
    strcpy(obj.client_name, name);
    cout << "Company: ";
    getline(in, obj.company);
    cout << "Marketing budget: ";
    in >> obj.marketing_budget;
    cout << "Contract: ";
    in >> obj.contract;

    return in;
}

ostream& operator<<(ostream& out, const Client& obj) {
    out << "---------------------------------------------------" << endl;
    out << "ClientID: " << obj.clientID << "\n";
    out << "Client name: "<< obj.client_name << "\n";
    out << "Number of clients: " << obj.numberOfClients << "\n";
    out << "Company: " << obj.company << "\n";
    out << "Marketing budget: " << obj.marketing_budget << "\n";
    out << "Contract: " << obj.contract << "\n";
    out << "---------------------------------------------------" << endl;

    return out;
};

class Campaign : public IOinterface, virtual public Client {
    private:
        char* campaign_name;
        vector<string> objectives;
        string socialMediaPlatform;
    public:
        void setCampaignName(const char* newCampaignName) {
            if(this->campaign_name != nullptr) {
                delete[] this->campaign_name;
                this->campaign_name = nullptr;
            }
            this->campaign_name = new char[strlen(newCampaignName) + 1];
            strcpy(this->campaign_name, newCampaignName);
        }
        const char* getCampaignName() {return this->campaign_name;}

        void setObjectives(const vector<string>& newObjectives) {this->objectives = objectives;}
        const vector<string>& getObjectives() {return this-> objectives;}

        void setSocialMediaPlatform(string newSocialMediaPlatform) {this->socialMediaPlatform = newSocialMediaPlatform;}
        string getSocialMediaPlatform() {return this->socialMediaPlatform;}

        Campaign();
        Campaign(const char* campaign_name, const vector<string> objectives, const string socialMediaPlatform);
        Campaign(const Campaign& obj);

        Campaign& operator=(const Campaign& obj);

        ~Campaign();

        friend istream& operator>>(istream& in, Campaign& obj);
        friend ostream& operator<<(ostream& out, const Campaign& obj);

};

Campaign::Campaign() {
    this->campaign_name = new char[strlen("NULL") + 1];
    strcpy(this->campaign_name, "NULL");
    this->objectives = {};
    this->socialMediaPlatform = "NULL";
};

Campaign::Campaign(const char* campaign_name, const vector<string> objectives, const string socialMediaPlatform) {
    this->campaign_name = new char[strlen(campaign_name) + 1];
    strcpy(this->campaign_name, campaign_name);
    this->objectives = objectives;
    this->socialMediaPlatform = socialMediaPlatform;
}

Campaign::Campaign(const Campaign& obj) {
    this->campaign_name = new char[strlen(obj.campaign_name) + 1];
    strcpy(this->campaign_name, obj.campaign_name);
    this->objectives = obj.objectives;
    this->socialMediaPlatform = obj.socialMediaPlatform;
}

Campaign& Campaign::operator=(const Campaign& obj) {
    if (this != &obj) {
        if(this->campaign_name != nullptr) {
            delete[] this-> campaign_name;
            this->campaign_name = nullptr;
        }
        this->campaign_name = new char[strlen(obj.campaign_name) + 1];
        strcpy(this->campaign_name, obj.campaign_name);
        this->objectives = obj.objectives;
        this->socialMediaPlatform = obj.socialMediaPlatform;
    }
    return *this;
}

Campaign::~Campaign() {
    if(this->campaign_name != nullptr) {
        delete[] this->campaign_name;
        this->campaign_name = nullptr;
    }
}

istream& operator>>(istream& in, Campaign &obj) {
    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: ";
    string temp;
    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: ";
    in >> obj.socialMediaPlatform;

    return in;
}

ostream& operator<<(ostream& out, const Campaign& obj) {
    out << "---------------------------------------------------" << endl;
    out << "Campaign name: " << obj.campaign_name << "\n";
    out << "Objectives: ";
    for (int i = 0; i < obj.objectives.size(); i++)
        if (i == 0) {
            out << "-" << obj.objectives[i] << endl;
        } else {
            out << "            -" << obj.objectives[i] << endl;
        }
    out << "Social media platform: " << obj.socialMediaPlatform << "\n";
    out << "---------------------------------------------------" << endl;

    return out;
}


int main() {
    Campaign a("pix", {"bani", "likes"}, "Instagram"), b;
    cin>>b;
    cout <<b;

}

我打字的时候想要

int main() {
 Client A;
 Campaign B;
 cin >> A >> B;
 cout << B;
}

提示输入有关客户端对象的详细信息,然后输入有关Campaign对象的详细信息,然后当它执行“cout << B”时,我希望在屏幕上看到Campaign对象的所有特定信息以及从客户端对象继承的一些内容。相反,对于那些从Client对象继承的东西,它显示NULL或0,就像在类的默认构造函数中一样。

gcxthw6b

gcxthw6b1#

下面介绍如何用现有代码实现所需的功能

int main()
{
    Client A;
    cin >> A;
    Campaign B;
    cin >> B;
    B.setClientName(A.getClientName());
    B.setCompany(A.getCompany());
    // etc etc
}

实际上,您必须将所有客户端信息从A复制到B
这不是一个好的设计。当一个类是另一个类的特殊化时,继承应该用来建模关系,例如圆是一种形状。这种关系有时被称为“是”关系。当一个类有另一个类作为属性时,这些关系被称为 * has-a * 关系,例如一个活动有一个客户。这种关系最好使用成员变量而不是继承来建模。因此,您的代码最好重写为使用成员资格而不是继承(类似于下面的代码)

class Client
{
    ...
};

class Campaign // no inheritance from Client
{
public:
    Client getCLient() const { return client; }
    void setClient(const Client& c) { client = c; }
    ...
private:
    ...
    Client client; // client member
};

int main()
{
    Client A;
    cin >> A;
    Campaign B;
    cin >> B;
    B.setClient(A);
}
lf5gs5x2

lf5gs5x22#

发明继承的一个传统原因是重用基类中的代码。Client有一个输入操作符;派生类Campaign的输入操作符应该首先调用Client基类的输入操作符,重用现有代码,然后提示在派生类中添加数据成员。这模仿了构造函数的工作方式,“由内而外”;但与编译器生成的构造函数相反,您必须使用输入函数显式地编写该构造函数。
这个设计是否好是另一个问题;在过去的二、三十年中,这种相对较强的耦合已经失去了吸引力(例如,继承经常被注入/成员关系所取代)。

相关问题