CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
+ Reply to Thread
Page 1 of 3 1 2 3 LastLast
Results 1 to 15 of 36
  1. #1
    Join Date
    Jun 2012
    Posts
    127

    generic inheritance

    Very simple idea:
    There was <template> Array that take class Point, multiply to a factor and print this bunch of objects of class Point

    Now I try to split Array to two template Array and NumericArray.
    NumericArray derived only multiplication operator...

    Pretty simple... but ((((

    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> NumericArray.cpp
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(7): error C2143: syntax error : missing ',' before '<'
    1> c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(15) : see reference to class template instantiation 'NumericArray<Type>' being compiled
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    h(7) and h(15) correspond open and close bracket of class

    my code :

    Code:
    //array.h
    
    #ifndef Array_H
    #define Array_H
    
    template <class Type> //Remove the "=double" default parameter.
    class Array
    {
    protected:
      int m_size;
      Type* m_data; //m_data should be a pointer, since you want to allocate data to it
     
    public:
      Array();
      Array(int new_size);
      ~Array(); //Don't make your destructor virtual. There is no reason to do it.
      Array<Type>& operator=(const Array& ar); //Const correctness here.
      //Type& operator * (double factor) const;
      Array operator *(double factor) const;   // 
      Type& operator [] (int index);
      const Type& operator [] (int index) const;
      int Size() const;
    };
    
    #ifndef Array_cpp 
    #include "array.cpp"
    #endif
     
    #endif //Array_CPP
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    //NumericArray.h
    
    #ifndef NumericArray_H
    #define NumericArray_H
    
    template <class Type> //Remove the "=double" default parameter.
    class NumericArray: public Array<Type>
    {
    	public: 
    	NumericArray();
    	NumericArray(int new_size);
    	~NumericArray(); //Don't make your destructor virtual. There is no reason to do it.
    	//NumericArray<Type>& operator=(const Array& ar); //Const correctness here.
    	NumericArray operator *(double factor) const;   // 
    };
    
    #endif 
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    //point.h
    
    #include "array.h"
    #include <sstream>
    #include <iostream>
    using namespace std;
    
    
    class Point
    {
    private:
        double m_x;                                
        double m_y;                                
    public:
        // Constructors
        Point(): m_x(0), m_y(0) {};                            
        Point(double new_x, double new_y) : m_x(new_x), m_y(new_y) {};
        friend ostream& operator << (ostream& os, const Point& point)
    {
        return os << point.ToString();
    }
        //std::string Point::ToString(void) const                // create a string representation of a point
       string ToString() const
    {
    // create a string like: “Point(1.5, 3.9)”
          std::ostringstream os;
        os << m_x << " , " << m_y;
        std::string double_string = os.str();
     
        return "Point(" + double_string + ")";
     
    }
        //Point Point::operator * (double factor) const;
        Point operator *(double factor) const;   
        //Point& Point::operator *= (double factor); 
        Point & operator *=(double factor);
    };
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    
    //array.cpp
    #include "Array.h"
    #include <sstream>
    #include <iostream>
    #include <exception>
    using namespace std;
    #ifndef Array_CPP
    #define Array_CPP
    
    
    template <class Type>
    Array<Type>::Array() : m_size(10), m_data(0) // странно получается, размер 10, а данных нет
    {
    }
    template <class Type>
    Array<Type>::Array(int new_size) : m_size(new_size), m_data(new Type[new_size])
    { 
    }
     
    template <class Type>
    Array<Type>::~Array()
    {
      //Technically, the if is not necessary
      if(m_data)
      {
        delete[] m_data;
        m_data = 0;
      }
     
      //Not necessary either, but just to be clean
      m_size = 0;
    }
     
     
     
    template <class Type>
    Array<Type>& Array<Type>::operator=(const Array& ar)
    {
      //Check self assign:
      if(this == &ar) {return *this;}
     
      Array<Type> copy(ar); //Create a copy of ar; If this fails, then *this will not be changed, and nothing will leak
     
      //Succeeded creating copy. Now we can put it inside this
      this->Swap(copy); //And then swap the copy into this!
     
      return *this;
    }
     
     
     
     
     
    template <class Type> 
    Type& Array<Type>::operator [] (int index) 
    {
        //cout << "Array [] operator" << endl;
     
        if (index > this->m_size)
        {
            cout << "i am hreeeee" << endl;
            return this->m_data[0];
        }
        return m_data[index];
    }
     
    template <class Type> 
     const Type& Array<Type>::operator [] (int index) const
     {
      //  cout << "Array [] operator" << endl;
     
        if (index > this->m_size)
        {
            cout << "i am hreeeee" << endl;
            return this->m_data[0];
        }
        return m_data[index];
    }
     
    template<class Type>
    int Array<Type>::Size() const
    {
        return this->m_size; 
    }
     
    /*template<class Type>
    //Type& Array<Type>::operator * (double factor) const
    Array<Type> Array<Type>::operator *(double factor) const
    {
       Array<Type> output(Array<Type>::Size());
       for(int i=0; i<Array::Size(); i++)
       {
          output[i] = (*this)[i] * factor;
          //return output;
       }
       return output;
    }
    */
    
    
    
    
    
     #endif //Array_CPP
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    //NumericArray.cpp
    #include "NumericArray.h"
    #include <sstream>
    #include <iostream>
    #include <exception>
    using namespace std;
    
    #ifndef NumericArray_CPP
    #define NumericArray_CPP
    
    
    template <class Type>
    NumericArray<Type>::NumericArray() : m_size(10), m_data(0) // странно получается, размер 10, а данных нет
    {
    }
    template <class Type>
    NumericArray<Type>::NumericArray(int new_size) : m_size(new_size), m_data(new Type[new_size])
    { 
    }
     
    template <class Type>
    NumericArray<Type>::~NumericArray()
    {
      //Technically, the if is not necessary
      if(m_data)
      {
        delete[] m_data;
        m_data = 0;
      }
     
      //Not necessary either, but just to be clean
      m_size = 0;
    }
    
    template<class Type>
    NumericArray<Type> NumericArray<Type>::operator *(double factor) const
    {
       NumericArray<Type> output(NumericArray<Type>::Size());
       for(int i=0; i<Array::Size(); i++)
       {
          output[i] = (*this)[i] * factor;
          //return output;
       }
       return output;
    }
    
     #endif //NumericArray_CPP
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    
    #include "Point.h"
    #include <sstream>
    #include <iostream>
    
    using namespace std;
     
      Point Point::operator * (double factor) const
    {
        return Point(m_x * factor, m_y * factor);
    }
     
     
        Point& Point::operator *= (double factor)
        {
        Point tmp = (*this) * factor;
        *this = tmp;
     
        return *this;
        }
    
    
    //****************
    //****************
    //****************
    
    
    //main.cpp
    		#include "point.h"
    		#include <iostream>
    		#include "array.cpp"
    		#include <exception>
    		#include "NumericArray.h"
    		using namespace std;
    
     
    int main()
    {
                  //Create two Point arrays and test the operators
        Array<Point> pArray1(5);
        Array<Point> pArray2(5);
        //initialize
        for(int i=0; i<pArray1.Size(); i++) pArray1[i] = Point(i, i);
        for(int i=0; i<pArray2.Size(); i++) pArray2[i] = Point(2*i, 2*i);
     
        //Numeric Array's operations not working for Point objects
     
     
        cout << "times PointArray1 by 3 and print out the new array: "<< endl;
        Array<Point> answ1 = pArray1 * 3;
        
        for(int i=0; i<answ1.Size(); i++){
            cout << answ1[i] << endl;
     
        }
     
     
        
    }
    
    //*******************
    //*******************
    //*******************
    //*******************
    Many many thanks in advance !

  2. #2
    Join Date
    Apr 1999
    Posts
    26,738

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    Very simple idea:
    There was <template> Array that take class Point, multiply to a factor and print this bunch of objects of class Point
    Where is line 7 and line 15?

    Second, now that you're deriving from Array, the Array class now needs a virtual destructor.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,273

    Re: generic inheritance

    You don't need to do that. Templates classes only compile the methods that are called. Methods that aren't called aren't compiled. They aren't even checked for legality (apart from proper grammar)

    This means that you can write an "Array" class, and give it a "Multiplication Feature".

    If the type is "multiplication compatible", then the user can write Array<Type>*double. And it works fine. If the user wants to multiply, he can multiply.

    If the type is not multiplicative, that doesn't prevent you from using it inside an array. You'll only run into problems if the caller trys to multiply, but that is normal.

    Code:
    #include <iostream>
    
    template <typename T>
    struct Holder
    {
      void shift(size_t s)
      {m_value <<= s;}
    
      T m_value;
    };
    
    int main()
    {
      Holder<int>    ih =   {5};
      Holder<double> id = {5.5};
    
      ih.shift(1);
      //id.shift(1); //Try to uncomment this
    
      std::cout << ih.m_value << " " << id.m_value;
    }
    Here, we have a "Holder", with a "shift" method. ints can be shifted, but doubles can't. This code compiles, but if you try to insert the call id.shift, then (and only then) will it not compile.

    This trick is actually used quite a lot, especially in stl containers.
    Is your question related to IO?
    Read this C++ FAQ LITE article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  4. #4
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,451

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> NumericArray.cpp
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(7): error C2143: syntax error : missing ',' before '<'
    1> c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(15) : see reference to class template instantiation 'NumericArray<Type>' being compiled
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    h(7) and h(15) correspond open and close bracket of class

    my code :

    Code:
    //NumericArray.h
    
    #ifndef NumericArray_H
    #define NumericArray_H
    
    template <class Type> //Remove the "=double" default parameter.
    class NumericArray: public Array<Type>
    {
    	public: 
    	NumericArray();
    	NumericArray(int new_size);
    	~NumericArray(); //Don't make your destructor virtual. There is no reason to do it.
    	//NumericArray<Type>& operator=(const Array& ar); //Const correctness here.
    	NumericArray operator *(double factor) const;   // 
    };
    No, line 7 is this one:
    Code:
    class NumericArray: public Array<Type>
    and it looks like you simply are not including array.h in NumericArray.cpp
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinViewer - an integrated GDI objects viewer for Visual C++ Debugger, and more...

  5. #5
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by VladimirF View Post
    No, line 7 is this one:
    Code:
    class NumericArray: public Array<Type>
    and it looks like you simply are not including array.h in NumericArray.cpp
    So silly mistake... and I also didn't include array.h in NumericArray.h
    so I done it. and...

    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1>main.obj : error LNK2001: unresolved external symbol "public: class Array<class Point> __thiscall Array<class Point>:perator*(double)const " (??D?$Array@VPoint@@@@QBE?AV0@N@Z)
    1>C:\all my\с++\HA level 6\Solution\Level 6\Release\HP3_4.2b_ex2_with_inheritance.exe : fatal error LNK1120: 1 unresolved externals
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


    Main idea message from console windows is that my project "isn't internal or external a command , that is used by program or batch file"
    Attached Images  
    Last edited by oteel; June 19th, 2012 at 01:54 PM.

  6. #6
    Join Date
    Apr 1999
    Posts
    26,738

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    1>main.obj : error LNK2001: unresolved external symbol "public: class Array<class Point> __thiscall Array<class Point>::operator*(double)const " (??D?$Array@VPoint@@@@QBE?AV0@N@Z)
    1>C:\all my\с++\HA level 6\Solution\Level 6\Release\HP3_4.2b_ex2_with_inheritance.exe : fatal error LNK1120: 1 unresolved externals
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    First, do you know what that error means?

    That is a linker error, not a compiler error. That error is saying that you're calling the operator* function, but it was not implemented. So where is the implementation for operator*?

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 19th, 2012 at 02:03 PM.

  7. #7
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by Paul McKenzie View Post
    Where is line 7 and line 15?

    Second, now that you're deriving from Array, the Array class now needs a virtual destructor.

    Regards,

    Paul McKenzie
    now compiler say me if I press ctrl + F7 (MS VS 2010) :
    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> Array.cpp
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> Array.cpp
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> Array.cpp
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> Array.cpp
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

    I implement what virtual detractor now I will be try to implement what monarch_dodra said... but still when I press ctrl + f5 (MS VS 2010) appears this error : 1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1>main.obj : error LNK2001: unresolved external symbol "public: class Array<class Point> __thiscall Array<class Point>:perator*(double)const " (??D?$Array@VPoint@@@@QBE?AV0@N@Z)
    1>C:\all my\с++\HA level 6\Solution\Level 6\Release\HP3_4.2b_ex2_with_inheritance.exe : fatal error LNK1120: 1 unresolved externals
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    and strange console window... that I mention before
    Last edited by oteel; June 19th, 2012 at 02:04 PM.

  8. #8
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by Paul McKenzie View Post
    First, do you know what that error means?

    That is a linker error, not a compiler error. That error is saying that you're calling the operator* function, but it was not implemented. So where is the implementation for operator*?

    Regards,

    Paul McKenzie
    just a second I post a code last edition

  9. #9
    Join Date
    Apr 1999
    Posts
    26,738

    Re: generic inheritance

    Why did you separate NumericArray.h and NumericArray.cpp into different files? NumericArray is a template class -- all the code goes in one file, and then you #include that file.

    Make it simple -- any template class you write goes in one file. I think that naming your template implementation files with a .cpp extension is confusing you.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    just a second I post a code last edition

    Code:
    //array.h //array.h //array.h //array.h //array.h //array.h //array.h //array.h //array.h //array.h 
    
    #ifndef Array_H
    #define Array_H
    
    template <class Type> //Remove the "=double" default parameter.
    class Array
    {
    protected:
      int m_size;
      Type* m_data; //m_data should be a pointer, since you want to allocate data to it
     
    public:
      Array();
      Array(int new_size);
     virtual ~Array(); //Don't make your destructor virtual. There is no reason to do it.
      Array<Type>& operator=(const Array& ar); //Const correctness here.
      //Type& operator * (double factor) const;
     // Array operator *(double factor) const;   // 
      Type& operator [] (int index);
      const Type& operator [] (int index) const;
      int Size() const;
    };
    
    #ifndef Array_cpp 
    #include "array.cpp"
    #endif
     
    #endif //Array_CPP
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h 
    #include "array.h"
    
    #ifndef NumericArray_H
    #define NumericArray_H
    
    template <class Type> //Remove the "=double" default parameter.
    class NumericArray: public Array<Type>
    {
    	public: 
    	NumericArray();
    	NumericArray(int new_size);
    	~NumericArray(); //Don't make your destructor virtual. There is no reason to do it.
    	//NumericArray<Type>& operator=(const Array& ar); //Const correctness here.
    	NumericArray operator *(double factor) const;   // 
    };
    
    #endif 
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    //point.h //point.h //point.h //point.h //point.h //point.h //point.h //point.h //point.h //point.h 
    
    #include "array.h"
    #include <sstream>
    #include <iostream>
    using namespace std;
    
    
    class Point
    {
    private:
        double m_x;                                
        double m_y;                                
    public:
        // Constructors
        Point(): m_x(0), m_y(0) {};                            
        Point(double new_x, double new_y) : m_x(new_x), m_y(new_y) {};
        friend ostream& operator << (ostream& os, const Point& point)
    {
        return os << point.ToString();
    }
        //std::string Point::ToString(void) const                // create a string representation of a point
       string ToString() const
    {
    // create a string like: “Point(1.5, 3.9)”
          std::ostringstream os;
        os << m_x << " , " << m_y;
        std::string double_string = os.str();
     
        return "Point(" + double_string + ")";
     
    }
        //Point Point::operator * (double factor) const;
        Point operator *(double factor) const;   
        //Point& Point::operator *= (double factor); 
        Point & operator *=(double factor);
    };
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    
    //array.cpp //array.cpp //array.cpp //array.cpp //array.cpp //array.cpp //array.cpp //array.cpp 
    #include "Array.h"
    #include <sstream>
    #include <iostream>
    #include <exception>
    using namespace std;
    #ifndef Array_CPP
    #define Array_CPP
    
    
    template <class Type>
    Array<Type>::Array() : m_size(10), m_data(0) // странно получается, размер 10, а данных нет
    {
    }
    template <class Type>
    Array<Type>::Array(int new_size) : m_size(new_size), m_data(new Type[new_size])
    { 
    }
     
    template <class Type>
    Array<Type>::~Array()
    {
      //Technically, the if is not necessary
      if(m_data)
      {
        delete[] m_data;
        m_data = 0;
      }
     
      //Not necessary either, but just to be clean
      m_size = 0;
    }
     
     
     
    template <class Type>
    Array<Type>& Array<Type>::operator=(const Array& ar)
    {
      //Check self assign:
      if(this == &ar) {return *this;}
     
      Array<Type> copy(ar); //Create a copy of ar; If this fails, then *this will not be changed, and nothing will leak
     
      //Succeeded creating copy. Now we can put it inside this
      this->Swap(copy); //And then swap the copy into this!
     
      return *this;
    }
     
     
     
     
     
    template <class Type> 
    Type& Array<Type>::operator [] (int index) 
    {
        //cout << "Array [] operator" << endl;
     
        if (index > this->m_size)
        {
            cout << "i am hreeeee" << endl;
            return this->m_data[0];
        }
        return m_data[index];
    }
     
    template <class Type> 
     const Type& Array<Type>::operator [] (int index) const
     {
      //  cout << "Array [] operator" << endl;
     
        if (index > this->m_size)
        {
            cout << "i am hreeeee" << endl;
            return this->m_data[0];
        }
        return m_data[index];
    }
     
    template<class Type>
    int Array<Type>::Size() const
    {
        return this->m_size; 
    }
     
    /*template<class Type>
    //Type& Array<Type>::operator * (double factor) const
    Array<Type> Array<Type>::operator *(double factor) const
    {
       Array<Type> output(Array<Type>::Size());
       for(int i=0; i<Array::Size(); i++)
       {
          output[i] = (*this)[i] * factor;
          //return output;
       }
       return output;
    }
    */
    
    
    
    
    
     #endif //Array_CPP
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    //NumericArray.cpp //NumericArray.cpp //NumericArray.cpp 
    #include "NumericArray.h"
    #include <sstream>
    #include <iostream>
    #include <exception>
    #include "array.h"
    using namespace std;
    
    #ifndef NumericArray_CPP
    #define NumericArray_CPP
    
    
    template <class Type>
    NumericArray<Type>::NumericArray() : m_size(10), m_data(0) // default filling of array is zeros!
    {
    }
    template <class Type>
    NumericArray<Type>::NumericArray(int new_size) : m_size(new_size), m_data(new Type[new_size])
    { 
    }
     
    template <class Type>
    NumericArray<Type>::~NumericArray()
    {
      //Technically, the if is not necessary
      if(m_data)
      {
        delete[] m_data;
        m_data = 0;
      }
     
      //Not necessary either, but just to be clean
      m_size = 0;
    }
    
    template<class Type>
    NumericArray<Type> NumericArray<Type>::operator *(double factor) const
    {
       NumericArray<Type> output(NumericArray<Type>::Size());
       for(int i=0; i<Array::Size(); i++)
       {
          output[i] = (*this)[i] * factor;
          //return output;
       }
       return output;
    }
    
     #endif //NumericArray_CPP
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    // Point.cpp // Point.cpp // Point.cpp // Point.cpp // Point.cpp // Point.cpp // Point.cpp // Point.cpp 
    #include "Point.h"
    #include <sstream>
    #include <iostream>
    
    using namespace std;
     
      Point Point::operator * (double factor) const
    {
        return Point(m_x * factor, m_y * factor);
    }
     
     
        Point& Point::operator *= (double factor)
        {
        Point tmp = (*this) * factor;
        *this = tmp;
     
        return *this;
        }
    
    
    //****************
    //****************
    //****************
    
    
    //main.cpp //main.cpp //main.cpp //main.cpp //main.cpp //main.cpp //main.cpp //main.cpp 
    		#include "point.h"
    		#include <iostream>
    		#include "array.cpp"
    		#include <exception>
    		#include "NumericArray.h"
    		using namespace std;
    
     
    int main()
    {
                  //Create two Point arrays and test the operators
        Array<Point> pArray1(5);
        Array<Point> pArray2(5);
        //initialize
        for(int i=0; i<pArray1.Size(); i++) pArray1[i] = Point(i, i);
        for(int i=0; i<pArray2.Size(); i++) pArray2[i] = Point(2*i, 2*i);
     
        //Numeric Array's operations not working for Point objects
     
     
        cout << "times PointArray1 by 3 and print out the new array: "<< endl;
        Array<Point> answ1 = pArray1 * 3;
        
        for(int i=0; i<answ1.Size(); i++){
            cout << answ1[i] << endl;
     
        }
     
     
        
    }
    
    //*******************
    //*******************
    //*******************
    //*******************

  11. #11
    Join Date
    Apr 1999
    Posts
    26,738

    Re: generic inheritance

    Code:
    #include "array.h"
    
    #ifndef NumericArray_H
    #define NumericArray_H
    Why is array.h outside of the include guards?
    Code:
    #ifndef NumericArray_H
    #define NumericArray_H
    
    #include "array.h"
    Second, you're supposed to include the implementation inside of NumericArray.h. All you have is the class definition, so where is the implementation?

    Regards,

    Paul McKenzie

  12. #12
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by Paul McKenzie View Post
    Why did you separate NumericArray.h and NumericArray.cpp into different files? NumericArray is a template class -- all the code goes in one file, and then you #include that file.

    Make it simple -- any template class you write goes in one file. I think that naming your template implementation files with a .cpp extension is confusing you.

    Regards,

    Paul McKenzie
    I doing what other doing I mean classmates))) If serious, I thinks main purpose of separating is that show new combination of pre processors... like including array.cpp in main not array.h like in class exercises

  13. #13
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by Paul McKenzie View Post
    Code:
    #include "array.h"
    
    #ifndef NumericArray_H
    #define NumericArray_H
    Why is array.h outside of the include guards?
    Code:
    #ifndef NumericArray_H
    #define NumericArray_H
    
    #include "array.h"
    Second, you're supposed to include the implementation inside of NumericArray.h. All you have is the class definition, so where is the implementation?

    Regards,

    Paul McKenzie

    this is from NumericArray.cpp
    Code:
    template<class Type>
    NumericArray<Type> NumericArray<Type>::operator *(double factor) const
    {
       NumericArray<Type> output(NumericArray<Type>::Size());
       for(int i=0; i<Array::Size(); i++)
       {
          output[i] = (*this)[i] * factor;
          //return output;
       }
       return output;
    }

  14. #14
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    I find that I implement operator * in Array and NumericalArray
    I commented out operator * from Array and what I get:

    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> main.cpp
    1>main.cpp(23): error C2676: binary '*' : 'Array<Type>' does not define this operator or a conversion to a type acceptable to the predefined operator
    1> with
    1> [
    1> Type=Point
    1> ]
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    1>main.cpp(23) -> Array<Point> answ1 = pArray1 * 3;

    Red line light * and pop up helper tell that "Error: no operantor "*" matches these operands"

  15. #15
    Join Date
    Apr 1999
    Posts
    26,738

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    I doing what other doing I mean classmates))) If serious, I thinks main purpose of separating is that show new combination of pre processors... like including array.cpp in main not array.h like in class exercises
    That is not how templates work, and that is the reason why you're getting a linker error.

    One more time -- for template classes, all the code must be in one source file.

    What you're doing is that you are separating NumericArray.cpp into its own module and compiling it. That is wrong. If anything, you would #include NumericArray.cpp within NumericArray.h.

    Look at what you did with the Array class. Do you see how you #included "array.cpp"? So why didn't you do the same thing with NumericArray.h?

    Regards,

    Paul McKenzie

+ Reply to Thread
Page 1 of 3 1 2 3 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts



HTML5 Development Center

Click Here to Expand Forum to Full Width