0

I have code that I am using to learn design patterns and C++ that has the tchar header, which I gather is a legacy header from Windows. I was thinking of switching to std::string but I don't know if I would be missing an important point in the inheritance or factory method by changing to the code shown later [my modification] and also not using strcpy_s.

Am I missing something important within the fundamentals of the factory design pattern or in C++? I am new to C++.

As it is:

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

My modification

class Product
{
protected:
    std::string _type;
public:
    Product()
    {
    }
    char *getType()
    {
        return _type;
    }
};
class ConcreteProduct : public Product
{
public:
    ConcreteProduct : Product()
    {
        std::string _type = "ConcreteProduct";
    }
};
heretoinfinity
  • 1,528
  • 3
  • 14
  • 33

1 Answers1

0

Your provided sample code is not actually using <tchar.h> (your character type should be _TCHAR in that case), but rather the basic C (not C++) string handling functions.

The idea of replacing this with std::string is very much the right idea - and you may wish to throw out the tutorial you are using for attempting to teach you differently.

The code you attempted to create has a few problems though. First off, the _type member field is now a std::string that cannot be implicitly converted to a char*, so your definition of the type function will not compile. Since you are modifying the example anyway, you can just return a const reference to your member:

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

Note that I also removed the erroneous Coffee() constructor (I assume that you intended to write Product here).

By writing Product() = default;´, we instruct C++ to automatically generate an empty constructor. You may have noticed that this constructor is nowprotected- we do not want the user of your class to be able to create aProduct` directly. (This may be the wrong thing to do, depending on your application.)

I have done the same thing to the copy and move operators to prevent object slicing, which many aspiring C++ programmers that first dip their toes into inheritance stumble over.

Finally, there is a constructor Product(std::string) that will initialize the _type member.

In the next step, you can derive from 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;
};

Note that we are now making the copy and move constructors public and are able to use the constructor syntax to intialize the base Product directly.

Full example

danielschemmel
  • 10,885
  • 1
  • 36
  • 58