Search code examples
c++oopobjectvectorhierarchy

Problems adding a class instance to a hierarchy of objects in C++


In our project we are required to create three classes: Customers, Campaigns and Advertisements. Each Customer has a vector of Campaigns, and each Campaign has a vector of Advertisements:

Customers -> Campaigns -> Advertisements

The problem arises for us when we are trying to add an Advertisement instance to a given customer's Campaign.

When we try to add an Advertisement to a given Campaign, we never see it actually adding the advertisement. The number of ads stay stagnant.

We are all new to C++ and not sure how to combat this with references, which we think relates to the issue.

The Customer class:

#pragma once
#include <vector>
#include <cstdio>
#include <string>
#include "campaign.h"

using namespace std;

class Customer
{
    string name;
    int id;
    vector<Campaign> campaigns;
public:


    Customer(string name, int id)
    {
        this->name = name;
        this->id = id;
    }

    string GetName()
    {
        return name;
    }

    void SetName(string name)
    {
        this->name = name;
    }

    int GetId()
    {
        return id;
    }

    void SetId(int id)
    {
        this->id = id;
    }

    bool AddCampaign(Campaign campaignObject)
    {
        campaigns.push_back(campaignObject);
        return true;
    }

    bool CommitAdvertisement(Ad ad, int campaignID)
    {
        for (int i = 0; i < campaigns.size(); i++)
        {
            if (campaigns[i].GetId() == campaignID)
            {
                campaigns[i].CommitAdvertisement(ad);
                return true;
            }
        }
        return false;
    }

    bool hasActiveCampaigns()
    {
        for (Campaign i : campaigns)
        {
            if (i.IsActive())
            {
                return true;
            }
        }
        return false;
    }

    vector<Campaign> GetAllCampaigns()
    {
        return campaigns;
    }

    vector<Ad> GetAllAdsForCampaign(int campaignID)
    {
        for (int i = 0; i < campaigns.size(); i++)
        {
            if (campaigns[i].GetId() == campaignID)
            {
                return campaigns[i].GetAllAds();
            }
        }
    }
};

The Campaign class:

#pragma once
#include <ctime>
#include <string>
#include <vector>
#include <iostream>
#include <exception>
#include <ctime>
#include "Ad.h"

using namespace std;


class Campaign
{
    string name;
    int id;
    time_t fromDateTime;
    time_t toDateTime;
    float campaignCost;
    vector<Ad> ads;

public:
    Campaign(time_t fromDateTime, time_t toDateTime, int id, string name, float campaignCost)
    {
        this->fromDateTime = fromDateTime;
        this->toDateTime = toDateTime;
        this->id = id;
        this->name = name;
        this->campaignCost = campaignCost;
    }

    time_t GetFromDateTime()
    {
        return fromDateTime;
    }

    void SetFromDateTime(time_t fromDateTime)
    {
        this->fromDateTime = fromDateTime;
    }

    time_t GetToDateTime()
    {
        return toDateTime;
    }

    void SetToDateTime(time_t toDateTime)
    {
        this->toDateTime = toDateTime;
    }

    int GetId()
    {
        return id;
    }

    void SetId(int id)
    {
        this->id = id;
    }

    string GetName()
    {
        return name;
    }

    void SetName(string name)
    {
        this->name = name;
    }

    float GetCampaignCost()
    {
        return campaignCost;
    }

    void SetCampaignCost(float campaignCost)
    {
        this->campaignCost = campaignCost;
    }

    bool IsActive()
    {
        time_t now = time(NULL);

        if (fromDateTime <= now && toDateTime >= now)
        {
            return true;
        }
        return false;
    }

    bool CommitAdvertisement(Ad ad)
    {
        for (Ad i : ads)
        {
            if (i.GetId() == ad.GetId())
            {
                return false;
            }
        }
        ads.push_back(ad);
        return true;
    }

    bool DeleteAdvertisement(int id)
    {
        for (int i = 0; i < ads.size(); i++)
        {
            if (ads[i].GetId() == id)
            {
                ads.erase(ads.begin() + i);
                return false;
            }
        }
        return false;
    }

    vector<Ad> GetAllAds()
    {
        return ads;
    }
};

The Ad class

#pragma once
#include <string>
#include <vector>
#include <iostream>
#include <exception>
#include "AdType.h"

using namespace std;

class Ad
{

private:

    string name;
    string adText;
    AdType adType; 
    int id;

public:

    Ad(string name, string text, int id, AdType type = AdType::PLAINTEXT)
    {
        this->name = name;
        this->adText = text;
        this->id = id;
        this->adType = type;
    }

    string GetName()
    {
        return name;
    }

    void SetName(string name)
    {
        this->name = name;
    }

    int GetId()
    {
        return id;
    }

    void SetId(int id)
    {
        this->id = id;
    }

    AdType GetType()
    {
        return adType;
    }

    void SetType(AdType type)
    {
        this->adType = type;
    }

    string GetText()
    {
        return adText;
    }

    void SetText(string adText)
    {
        this->adText = adText;
    }
};

Now, we've successfully added a campaign to a given customer, and are able to add one ad instance but no more.

This code snippet shows this attempt:

    // Create a customer
    Customer *the_client = new Customer("Foobar Inc", 123);

    // Create a campaign
    Campaign *the_campaign = new Campaign(begin, end, 1234, "campaign_name", 123455.0f);

    // Create an ad
    Ad *the_first_ad = new Ad("First ad", "adtext", 12345656, AdType::PLAINTEXT);

    // create another ad
    Ad* the_second_ad = new Ad("Second ad", "adtext", 12345656, AdType::PLAINTEXT);

    // add the campaign to the customer
    the_client->AddCampaign(*the_campaign);

    // Add the ad to the customers' list of ads
    the_client->CommitAdvertisement(*the_first_ad, 1234);

    // Print out how many ads there are in the given campaign
    cout << "There are now " << the_client->GetAllAdsForCampaign(1234).size() << "ads int the campaign" << endl;

    // Add the second ad to the customers' list of ads
    the_client->CommitAdvertisement(*the_second_ad, 1234);

    // Again - print out how many ads there are in the given campaign
    cout << "There are now " << the_client->GetAllAdsForCampaign(1234).size() << "ads int the campaign" << endl;

It's very possible we are totally doing this wrong, but any guidance is more than welcome.


Solution

  • CommitAdvertisement will return false and fail to add it if there is already an advertisement with the same id.

    And that is what you're doing. The first and second ads both have id 12345656. So it's doing what you asked of it.

    Increment the id for the_second_ad.