Является ли использование "фиктивных" объектов для облегчения OOP приемлемым в C ++, и существует ли лучшая альтернатива? - PullRequest
0 голосов
/ 28 апреля 2020

Я очень новичок в C ++, и работая с упражнениями в моем учебнике, в которых используются определяемые пользователем классы, я обнаружил, что полезно создавать объекты "фиктивных" / "заполнителей", единственное назначение которых состоит в том, чтобы облегчить использование функций. / векторы в `int main () '. Полученные мной ошибки компилятора указывают на то, что такие векторы и функции необходимо присоединять к объекту класса, поэтому я создал фиктивный объект для удовлетворения этой потребности.

Мне интересно, является ли это приемлемой практикой программирования, или если существуют лучшие альтернативы. (Также, если для этой практики есть более распространенный термин, чем «фиктивные объекты», пожалуйста, дайте мне знать.)

Я включил следующую «программу» в качестве примера. Food x не имеет реального значения само по себе; однако, это позволяет мне использовать векторы 'foodentry ()' и 'favourfoods' внутри 'int main ()', так как кажется, что эти элементы должны быть присоединены к объекту, а «Food x» является единственным объектом У меня есть.

Спасибо, как всегда, за ваш вклад.

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 << " ";
    }
}

1 Ответ

1 голос
/ 28 апреля 2020

Тот факт, что вам нужен фиктивный объект, несколько указывает на не совсем идеальный дизайн класса.

Спросите себя, что означает Food? Казалось бы, он должен представлять пару названий продуктов, представляющих любимый фрукт и десерт. Кажется, нет причины для этого класса также содержать коллекцию Food самих объектов (такая композиция обычно встречается в реализациях иерархических структур данных) . Здесь это не имеет никакого отношения.

Как правило, вы бы структурировали простую программу такого рода, например:

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);
    ...
}

На некотором уровне сложности вы можете захотеть инкапсулировать вектор и FoodEntry метод для выделенного класса, например FoodCollector.

...