Search code examples
c++oopobjectprogram-entry-point

Is using "dummy" objects to facilitate OOP acceptable in C++, and does a better alternative exist?


I am very new to C++, and in working through exercises in my textbook that use user-defined classes, I have found it helpful to create "dummy"/"placeholder" objects whose only purpose is to facilitate the use of functions/vectors in `int main()'. The compiler errors I received indicate that such vectors and functions need to be attached to an object of a class, so I created a dummy object to meet that need.

I am wondering if this is an acceptable programming practice, or if better alternatives exist. (Also, if there is a more common term for this practice than "dummy objects," please let me know.)

I have included the following 'program' as an example. Food x has no real significance on its own; however, it allows me to use the 'foodentry()' and 'favoritefoods' vector within 'int main()', as it appears that those items need to be attached to an object--and 'Food x' is the only object I have.

Thank you as always for your input.

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

class Food
{
public:
    string favoritefruit;
    string favoritedessert;
    vector<Food> favoritefoods;
    Food(string a, string b)
        : favoritefruit(a), favoritedessert(b) {}
    void foodentry();
};
//"Placeholder" object. It doesn't do anything except allow me
//to use the function and vector entries in int (main). If I
//don't precede the function and vector entries in int (main)
//with the object x, they show up as undefined. Is there 
//another way to get the function and vector entries in int //main() to work?
Food x{" ", " "};

void Food::foodentry()
{
    cout << "Please enter your favorite fruit, other than oranges:\n";
    cin >> favoritefruit;
    cout << "Now please enter your favorite dessert, other than cookies:\n";
    cin >> favoritedessert;
    favoritefoods.push_back(Food{favoritefruit, favoritedessert});
}

int main()

{
    x.favoritefoods.push_back(Food{"oranges", "cookies"});
    x.foodentry();

    cout << "Here are two great fruits: ";
    for (int y = 0; y < x.favoritefoods.size(); y++)
    {
        cout << x.favoritefoods[y].favoritefruit << " ";
    }
    cout << "\nAnd here are two great desserts: ";
    for (int y = 0; y < x.favoritefoods.size(); y++)
    {
        cout << x.favoritefoods[y].favoritedessert << " ";
    }
}

Solution

  • The fact that you need the dummy object is somewhat indicative of less than ideal class design.

    Ask yourself, what does Food represent? It would seem that it should represent a pair of food names, representing one's favorite fruit and dessert. There does not seem to be a reason for this class to also contain a collection of Food objects itself (this kind of composition is usually found in implementations of hierarchical data structures). It has no relevance here.

    More typically, you would structure a simple program of this nature like this:

    class Food
    {
    public:
        string favoritefruit;
        string favoritedessert;
    };
    
    void FoodEntry(std::vector<Food>& Foods) <-- note: passed by reference
    {
       ...
    }
    
    int main()
    {
        std::vector<Food> foods;
        foods.push_back(Food{"oranges", "cookies"});
        FoodEntry(foods);
        ...
    }
    

    At some level of complexity, you may want to encapsulate the vector and FoodEntry method to a dedicated class, e.g. FoodCollector.