Фабричный метод: разница в назначении и strcpy_s - PullRequest
0 голосов
/ 18 января 2020

У меня есть код, который я использую для изучения шаблонов проектирования, и C ++ с заголовком tchar, который, как я понимаю, является устаревшим заголовком из Windows. Я думал о переключении на std::string, но я не знаю, упустил ли я важный момент в методе наследования или фабрики, изменив код, показанный ниже [ моя модификация ], а также не используя strcpy_s.

Мне не хватает чего-то важного в основах шаблона проектирования фабрики или в C ++? Я новичок в C ++.

Как есть:

class Product
{
protected:
    char _type[15];
public:
    Product()
    {
    }
    char *getType()
    {
        return _type;
    }
};
class ConcreteProduct : public Product
{
public:
    ConcreteProduct : Product()
    {
        strcpy_s(_type, "ConcreteProduct");
    }
};

Моя модификация

class Product
{
protected:
    std::string _type;
public:
    Product()
    {
    }
    char *getType()
    {
        return _type;
    }
};
class ConcreteProduct : public Product
{
public:
    ConcreteProduct : Product()
    {
        std::string _type = "ConcreteProduct";
    }
};

1 Ответ

0 голосов
/ 19 января 2020

Ваш предоставленный пример кода на самом деле не использует <tchar.h> (ваш тип символа должен быть _TCHAR в этом случае), а скорее базовые c C (не C ++) функции обработки строк .

Идея заменить это на std::string очень правильная идея, и вы можете sh выбросить учебник, который вы используете для попытки научить вас по-другому.

Код, который вы пытались создать, имеет несколько проблем. Прежде всего, поле члена _type теперь является std::string, которое не может быть неявно преобразовано в char*, поэтому ваше определение функции type не будет компилироваться. Так как вы все равно изменяете пример, вы можете просто вернуть ссылку const вашему члену:

class Product {
protected:
    std::string _type;

    Product() = default;
    Product(Product const&) = default;
    Product& operator=(Product const&) = default;
    Product(Product &&) = default;
    Product& operator=(Product &&) = default;

    Product(std::string _type) : _type(std::move(_type)) { }

public:
    std::string const& getType() { return _type; }
};

Обратите внимание, что я также удалил ошибочный конструктор Coffee() (я предполагаю, что вы намеревались написать Product здесь).

Письмо Product() = default;´, we instruct C++ to automatically generate an empty constructor. You may have noticed that this constructor is now защищено - we do not want the user of your class to be able to create a Товар` напрямую. (Это может быть неправильно, в зависимости от вашего приложения.)

Я сделал то же самое для операторов копирования и перемещения, чтобы предотвратить разрезание объектов , к чему многие стремящиеся программисты на C ++ которые сначала опускают свои пальцы в спотыкание о наследовании.

Наконец, есть конструктор Product(std::string), который инициализирует член _type.

На следующем шаге вы можете получить из Product:

class ConcreteProduct : public Product {
public:
    ConcreteProduct() : Product("ConcreteProduct") { }
    ConcreteProduct(ConcreteProduct const&) = default;
    ConcreteProduct& operator=(ConcreteProduct const&) = default;
    ConcreteProduct(ConcreteProduct &&) = default;
    ConcreteProduct& operator=(ConcreteProduct &&) = default;
};

Обратите внимание, что теперь мы делаем конструкторы копирования и перемещения общедоступными c и можем использовать синтаксис конструктора для непосредственной инициализации базы Product.

Полный пример

...