0

I recently switched to C++ from JAVA. I am trying to implement Factory Design Pattern.

Here are my files.

Shape.h

    #pragma once

    class Ishape
    {
    public:
        virtual void draw()=0;
    };

Rectangle.h

    #pragma once
    #include"Shape.h"
    class Rectangle :public Ishape
    {
    public:
        void draw();
    };

Rectangle.cpp

    #include"Rectangle.h"
    #include<iostream>
    void draw()
    {
        std::cout << "Rectangle Draw" << std::endl;
    }

Square.h

    #pragma once
    #include"Shape.h"

    class Square :public Ishape
    {
    public:
        void draw();
    };

Square.cpp

    #include"Square.h"
    #include<iostream>

    void draw()
    {
        std::cout << "Square Draw" << std::endl;
    }

ShapeFactory.h

    #pragma once
    #include "Shape.h"
    #include<iostream>
    class ShapeFactory
    {
    public:
        static Ishape* getShape(std::string type);
    };

ShapeFactory.cpp

    #include"ShapeFactory.h"
    #include"Rectangle.h"
    #include"Square.h"


    static Ishape* getShape(std::string type)
    {
        Ishape* s = nullptr;
        if (type == "Rectangle")
        {
            s= new Rectangle;
        }
        else if (type == "Square")
        {
            s= new Square;
        }
        return s;
    }

Client Code:

Source.cpp

    #include<iostream>
    #include"ShapeFactory.h"
    int main()
    {
        using namespace std;
        Ishape* shape = ShapeFactory::getShape("Rectangle");
        shape->draw();
        return 0;
    }

When I run this,I got the following Run-Time Errors:

    Severity    Code    Description Project File    Line    Suppression State
    Error   LNK2005 "void __cdecl draw(void)" (?draw@@YAXXZ) already defined in Rectangle.obj       1   
    Error   LNK2019 unresolved external symbol "public: static class Ishape * __cdecl ShapeFactory::getShape(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?getShape@ShapeFactory@@SAPAVIshape@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main Project1    C:\Users\nikhil\source\repos\Project1\Project1\Source.obj   1   
    Error   LNK1120 1 unresolved externals  Project1    C:\Users\nikhil\source\repos\Project1\Debug\Project1.exe    1   

Few Points: I read that It is good practice to keep separate header files and code files,that is why I followed that.

I followed this example of Factory Design Pattern.(https://www.tutorialspoint.com/design_pattern/factory_pattern.htm)

Can anyone please suggest,how to overcome the error.Any other tips from c++ point will also be helpful.

somerandomguy
  • 323
  • 4
  • 13
  • 4
    These are linker errors not runtime errors. – drescherjm Aug 06 '18 at 18:59
  • oh,How can i fix them? – somerandomguy Aug 06 '18 at 19:00
  • 3
    You created 2 free functions named `draw()`. They have no relation to your classes. the linker is complaining about you violating the one definition rule. – drescherjm Aug 06 '18 at 19:01
  • I want to apply polymorphism to call draw function of the object returned by factory. – somerandomguy Aug 06 '18 at 19:03
  • 1
    You might be interested in [The Definitive C++ Book Guide and List](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – molbdnilo Aug 06 '18 at 19:03
  • 2
    "I recently switched to C++ from JAVA" - then step one should be to forget everything you know about Java and approach C++ as a completely new language. There are syntactical similarities, but that's as far as it goes, the semantics of seemingly identical constructs are often quite different. Just a tip. – Jesper Juhl Aug 06 '18 at 19:07
  • The answer (although downvoted) should work except you made the same error again with getShape() – drescherjm Aug 06 '18 at 19:10
  • Rectangle :: draw and Square:: draw are not treated as different? – somerandomguy Aug 06 '18 at 19:22
  • `void draw() { ...` when declared outside the class definition is a free function (not part of a class). `void Rectangle::draw() { ...` is a class member function of the Rectangle class. – drescherjm Aug 06 '18 at 19:24

1 Answers1

0

Rectangle.cpp

#include"Rectangle.h"
#include<iostream>
void Rectangle::draw()
//   ^^^^^^^^^^^
{
    std::cout << "Rectangle Draw" << std::endl;
}

Square.cpp

#include"Square.h"
#include<iostream>

void Square::draw()
//   ^^^^^^^^
{
    std::cout << "Square Draw" << std::endl;
}

ShapeFactory.cpp

#include"ShapeFactory.h"
#include"Rectangle.h"
#include"Square.h"


static Ishape* getShape(std::string type)
{
    Ishape* s = nullptr;
    if (type == "Rectangle")
    {
        s= new Rectangle;
    }
    else if (type == "Square")
    {
        s= new Square;
    }
    return s;
}

You've done all right in terms of OOP. But apparently you don't understand common principles of c++. When you writes void draw() in Rectangle.cpp you definitions actually free function, but no Rectangle's member-method (similarly in the other cases)

acade
  • 245
  • 2
  • 7
  • the two classes Rectangle and Square extends from Ishape and defines their own draw.Can I use this to apply polmorphism – somerandomguy Aug 06 '18 at 19:07