CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 36
  1. #16
    Join Date
    Apr 1999
    Posts
    26,799

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    I find that I implement operator * in Array and NumericalArray
    I commented out operator * from Array and what I get:
    Why are you commenting out code that your program is calling?

    You should stop commenting out code and address the real problem, which I've stated in my previous posts. Your issue is a linker issue, all because you're separating template code into its own compilation unit.

    Regards,

    Paul McKenzie

  2. #17
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by Paul McKenzie View Post
    Why are you commenting out code that your program is calling?

    You should stop commenting out code and address the real problem, which I've stated in my previous posts. Your issue is a linker issue, all because you're separating template code into its own compilation unit.

    Regards,

    Paul McKenzie
    eeeeeeee
    Attached Images Attached Images  

  3. #18
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by Paul McKenzie View Post
    Why are you commenting out code that your program is calling?

    You should stop commenting out code and address the real problem, which I've stated in my previous posts. Your issue is a linker issue, all because you're separating template code into its own compilation unit.

    Regards,

    Paul McKenzie
    But I need that operator * will be in NumericArray not in Array template... because of this I commented out declaration and implementation operator * in Array. h and Array.cpp
    Why is it wrong ?
    BTW this result I get when I uncommented operator * in Array...

  4. #19
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by Paul McKenzie View Post
    Why are you commenting out code that your program is calling?

    You should stop commenting out code and address the real problem, which I've stated in my previous posts. Your issue is a linker issue, all because you're separating template code into its own compilation unit.

    Regards,

    Paul McKenzie
    I mean from condition I should call operator * from NumericalArray not from Array
    and relationship between those two template should be hierarchy (ISA if I not mistaken )

    this is 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;   // 
    };
    
    #ifndef NumericArray_cpp 
    #include "NumericArray.cpp"
    #endif
    
    #endif // NumericArray
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    
    //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 //NumericArray.cpp //NumericArray.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
    #include "array.h"
    
    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;
     
        }
     
     
        
    }
    
    //*******************
    //*******************
    //*******************
    //*******************
    Last edited by oteel; June 19th, 2012 at 02:40 PM.

  5. #20
    Join Date
    Apr 1999
    Posts
    26,799

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    But I need that operator * will be in NumericArray not in Array template...
    Why are you making this so difficult? Take that code in NumericArray.cpp and #include it in NumericArray.h.
    How hard is that?

    You also did not fix the issue with the included code outside of the include guards? Why not?

    Also, take this out of NumericArray.cpp
    Code:
    #include "NumericArray.h"
    Why are you #including NumericArray.h? You're supposed to be taking this code in NumericArray.cpp and including it in NumericArray.h, not the other way around.

    Let's make this simple -- put everything in one file, NumericArray.h and delete, erase, get rid of NumericArray.cpp Now we have no NumericArray.cpp to confuse you.

    Now NumericArray.h looks like this:
    Code:
    #ifndef NumericArray_H
    #define NumericArray_H
    
    #include "array.h"
    
    template <class Type> 
    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<Type>& ar); 
             NumericArray operator *(double factor) const;    
    };
    
    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;
    }
    
    template <class Type>
    NumericArray<Type>& NumericArray<Type>::operator=(const Array& ar) 
    
    #endif
    Understand now? Forget about NumericArray.cpp and just do the above.

    Now that we have the code above, why are you duplicating exactly the same code from the Array class? You are deriving from the Array class, so why are you duplicating the code? Just call the parent Array class instead of rewriting everything.

    Secondly, your assignment operator is not correct. It must take a NumericArray<Type> reference as a parameter, not an Array<Type>.

    Regards,

    Paul McKenzie

  6. #21
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    You also did not fix the issue with the included code outside of the include guards? Why not?
    I thought that this is putting #include files like h and cpp after #define and #ifndef ??? or I'm mistaken

    Understand now? Forget about NumericArray.cpp and just do the above.
    Done

    Secondly, your assignment operator is not correct. It must take a NumericArray<Type> reference as a parameter, not an Array<Type>.
    done

    Now that we have the code above, why are you duplicating exactly the same code from the Array class? You are deriving from the Array class, so why are you duplicating the code? Just call the parent Array class instead of rewriting everything.
    done...

    compiler error:
    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> main.cpp
    1>main.cpp(9): error C2143: syntax error : missing ';' before 'using'
    1>main.cpp(9): error C2143: syntax error : missing ';' before '<end Parse>'
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


    last edition of my code:

    Code:
    //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> 
    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(); //Are there reason making destructor virtual?
      Array<Type>& operator=(const Array& ar); //Const correctness here.
      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 
    
    
    #ifndef NumericArray_H
    #define NumericArray_H
    
    #include "array.h"
    
    template <class Type> 
    class NumericArray: public Array<Type>
    {
        public: 
            NumericArray();
            NumericArray(int new_size);
           ~NumericArray(); 
            NumericArray<Type>& operator=(const NumericArray<Type>& ar); 
            NumericArray<Type>& operator *(double factor) const;    
    };
    
    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(Array<Type>::Size());
       for(int i=0; i<Array::Size(); i++)
       {
          output[i] = (*this)[i] * factor;
          //return output;
       }
       return output;
    }
    
    template <class Type>
    NumericArray<Type>& NumericArray<Type>::operator=(const NumericArray& ar) 
    
    #endif //NumericArray_h 
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    
    
    //point.h //point.h //point.h //point.h //point.h //point.h //point.h //point.h //point.h //point.h 
    #include <sstream>
    #include <iostream>
    
    #ifndef Point_H
    #define Point_H
    #include "array.h"
    
    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);
    };
    
    #endif //Point_h
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    //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) // 
    {
    }
    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) 
    {
        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
    
    //*******************
    //*******************
    //*******************
    //*******************
    
    // 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 "Array.h"
    		#include "array.cpp"
    	//	#include <exception>
    		#include "NumericArray.h"
    		#include <iostream>
    		using namespace std;
    int main()
    {
                  //Create two Point arrays and test the operators
        NumericArray<Point> pArray1(5);
        NumericArray<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;
        NumericArray<Point> answ1 = pArray1 * 3;
        
        for(int i=0; i<answ1.Size(); i++)
    	{
            cout << answ1[i] << endl;
        }
    }
    Last edited by oteel; June 20th, 2012 at 03:55 AM.

  7. #22
    Join Date
    Apr 1999
    Posts
    26,799

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    I thought that this is putting #include files like h and cpp after #define and #ifndef ??? or I'm mistaken
    No.

    Just put the include file within the include guards. It makes no sense to have an include file, and some of it is sticking outside of the include guards -- plain and simple.
    1>main.cpp(9): error C2143: syntax error : missing ';' before 'using'
    1>main.cpp(9): error C2143: syntax error : missing ';' before '<end Parse>'
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    So you cannot fix this error? At some point you'll have to take the lead and fix your own compiler errors. You can't just repeatedly get a compiler error and not know what to do.

    What do you think is the problem?

    Also, it would help if you placed your code in individual code blocks, and not have everything placed in a single code block. No one can tell what is an individual module, where one file starts and one file ends, etc... Then you don't need comments like this:
    Code:
     
    // array.h array.h array.h array.h
    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 20th, 2012 at 03:59 AM.

  8. #23
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    What do you think is the problem?
    Problem with my brain... after one year of practice I'll be laugh about those posts and threads...
    It happen every time that I try to learn some new for me big stuff...

    If serious let me think...

    I think this place
    Code:
    }
    
    template <class Type>
    NumericArray<Type>& NumericArray<Type>::operator=(const Array& ar) 
    
    #endif
    from NumerArray.h
    Last edited by oteel; June 20th, 2012 at 04:17 AM.

  9. #24
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    okey I'm done previous mistake... There weren't realization of assignment operator if shortly
    no there is other one problem...


    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> main.cpp
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(30): error C2614: 'NumericArray<Type>' : illegal member initialization: 'm_data' is not a base or member
    1> with
    1> [
    1> Type=Point
    1> ]
    1> c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(29) : while compiling class template member function 'NumericArray<Type>::NumericArray(int)'
    1> with
    1> [
    1> Type=Point
    1> ]
    1> main.cpp(14) : see reference to class template instantiation 'NumericArray<Type>' being compiled
    1> with
    1> [
    1> Type=Point
    1> ]
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(30): error C2614: 'NumericArray<Type>' : illegal member initialization: 'm_size' is not a base or member
    1> with
    1> [
    1> Type=Point
    1> ]
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(66): warning C4172: returning address of local variable or temporary
    1> c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(59) : while compiling class template member function 'NumericArray<Type> &NumericArray<Type>:perator *(double) const'
    1> with
    1> [
    1> Type=Point
    1> ]
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


    "'m_data' is not a base or member" BUT WHY ???
    I'm realize inherent and made data member on parents template protected (not private)... What is wrong again ?

    PS this is realization of assignment operator in NumerArray.h

    Code:
     template <class Type>
    NumericArray<Type>& NumericArray<Type>::operator=(const NumericArray& 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;
    }

  10. #25
    Join Date
    Apr 1999
    Posts
    26,799

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    okey I'm done previous mistake... There weren't realization of assignment operator if shortly
    no there is other one problem...
    Code:
    NumericArray<Type>& NumericArray<Type>::operator=(const NumericArray& ar)
    Where is the template argument?

    Second, and again, why are you repeating code that is already in the Array parent class? Do you not see that you're copying and pasting code from Array into NumericArray? Doesn't that sound wasteful to you?
    Code:
    template <class Type>
    NumericArray<Type>& NumericArray<Type>::operator=(const NumericArray<Type>& ar) 
    {
         Array<Type>::operator = (ar);  // call base class assignment operator
         return *this;
    }
    The bottom line is this --

    You have a base class, it does work. You derive from that base class, so why don't you make the base class do its work? Instead, you're copying that work and putting it in the derived class. Why are you doing that?

    Regards,

    Paul McKenzie

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

    Re: generic inheritance

    Quote Originally Posted by Paul McKenzie View Post
    Code:
    NumericArray<Type>& NumericArray<Type>::operator=(const NumericArray& ar)
    Where is the template argument?
    That's legal code right there actually, as far as I'm concerned.

    Quote Originally Posted by oteel View Post
    "'m_data' is not a base or member" BUT WHY ???
    I'm realize inherent and made data member on parents template protected (not private)... What is wrong again ?
    m_data is a member of "Array", which means it is owned and constructed by Array, in Array's constuctor. While NumericArray can manipulate that member afterwards, it can't construct it.

    Long story short, write this:
    Code:
    template <class Type>
    NumericArray<Type>::NumericArray() : Array() //Array constructs m_data
    {
    }
    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.

  12. #27
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    You have a base class, it does work. You derive from that base class, so why don't you make the base class do its work? Instead, you're copying that work and putting it in the derived class. Why are you doing that?
    I don't understand question sorry... and I don't understand what difference between your and my implementation assignment operator... more compact and more logic because call base class assignment ??? I not sure that my implementation incorrect... but it's lyrical digression... i suppose because the mistake is still the same

  13. #28
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    Quote Originally Posted by monarch_dodra View Post
    That's legal code right there actually, as far as I'm concerned.



    m_data is a member of "Array", which means it is owned and constructed by Array, in Array's constuctor. While NumericArray can manipulate that member afterwards, it can't construct it.

    Long story short, write this:
    Code:
    template <class Type>
    NumericArray<Type>::NumericArray() : Array() //Array constructs m_data
    {
    }



    Code:
    //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h 
    
    
    #ifndef NUMERICARRAY_H
    #define NUMERICARRAY_H
    
    #include "array.h"
    
    template <class Type> 
    class NumericArray: public Array<Type>
    
    {
        public: 
            NumericArray();
            NumericArray(int new_size);
           ~NumericArray(); 
            NumericArray<Type>& operator=(const NumericArray<Type>& ar); 
            NumericArray<Type>& operator *(double factor) const;    
    };
    
    template <class Type>
    NumericArray<Type>::NumericArray():Array() //: m_size(10), m_data(0) // default filling of array is zeros!
    {
    }
    
    template <class Type>
    NumericArray<Type>::NumericArray(int new_size) :  Array(int new_size)//: m_size(new_size), m_data(new Type[new_size])
    { 
    }
     
    template <class Type>
    NumericArray<Type>& NumericArray<Type>::operator=(const NumericArray<Type>& ar) 
    {
         Array<Type>::operator = (ar);  // call base class assignment operator
         return *this;
    }
    
    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(Array<Type>::Size());
       for(int i=0; i<Array::Size(); i++)
       {
          output[i] = (*this)[i] * factor;
          //return output;
       }
       return output;
    }
    #endif //NumericArray_h 
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> &#160;main.cpp
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(27): error C2144: syntax error : 'int' should be preceded by ')'
    1> &#160; &#160; &#160; &#160; &#160;c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(27) : while compiling class template member function 'NumericArray<Type>::NumericArray(int)'
    1> &#160; &#160; &#160; &#160; &#160;with
    1> &#160; &#160; &#160; &#160; &#160;[
    1> &#160; &#160; &#160; &#160; &#160; &#160; &#160;Type=Point
    1> &#160; &#160; &#160; &#160; &#160;]
    1> &#160; &#160; &#160; &#160; &#160;main.cpp(14) : see reference to class template instantiation 'NumericArray<Type>' being compiled
    1> &#160; &#160; &#160; &#160; &#160;with
    1> &#160; &#160; &#160; &#160; &#160;[
    1> &#160; &#160; &#160; &#160; &#160; &#160; &#160;Type=Point
    1> &#160; &#160; &#160; &#160; &#160;]
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(27): error C2612: trailing 'type' illegal in base/member initializer list
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(27): error C2059: syntax error : ')'
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(27): error C2082: redefinition of formal parameter 'new_size'
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(27): error C2059: syntax error : ':'
    1>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\xmemory(217): error C2143: syntax error : missing ';' before '<end Parse>'
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(40): error C2143: syntax error : missing ';' before '{'
    1>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\xmemory(217): error C2143: syntax error : missing ';' before '<end Parse>'
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(53): error C2143: syntax error : missing ';' before '{'
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(57): error C2065: 'factor' : undeclared identifier
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(60): error C2534: 'NumericArray<Type>' : constructor cannot return a value
    1> &#160; &#160; &#160; &#160; &#160;with
    1> &#160; &#160; &#160; &#160; &#160;[
    1> &#160; &#160; &#160; &#160; &#160; &#160; &#160;Type=Point
    1> &#160; &#160; &#160; &#160; &#160;]
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(60): error C2562: 'NumericArray<Type>::NumericArray' : 'void' function returning a value
    1> &#160; &#160; &#160; &#160; &#160;with
    1> &#160; &#160; &#160; &#160; &#160;[
    1> &#160; &#160; &#160; &#160; &#160; &#160; &#160;Type=Point
    1> &#160; &#160; &#160; &#160; &#160;]
    1> &#160; &#160; &#160; &#160; &#160;c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(15) : see declaration of 'NumericArray<Type>::NumericArray'
    1> &#160; &#160; &#160; &#160; &#160;with
    1> &#160; &#160; &#160; &#160; &#160;[
    1> &#160; &#160; &#160; &#160; &#160; &#160; &#160;Type=Point
    1> &#160; &#160; &#160; &#160; &#160;]
    1>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\xmemory(217): error C2143: syntax error : missing ';' before '<end Parse>'
    1>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\utility(78): error C2143: syntax error : missing ';' before '{'
    1>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\utility(79): error C2065: '_Ty' : undeclared identifier
    1>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\utility(79): error C2059: syntax error : ')'
    1>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\xmemory(217): error C2143: syntax error : missing ';' before '<end Parse>'
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



    Again mistakes (((

  14. #29
    Join Date
    Jun 2012
    Posts
    127

    Re: generic inheritance

    This realization is compiled but with some warnings see below :

    Code:
    //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h //NumericArray.h 
    
    
    #ifndef NUMERICARRAY_H
    #define NUMERICARRAY_H
    
    #include "array.h"
    
    template <class Type> 
    class NumericArray: public Array<Type>
    
    {
        public: 
            NumericArray();
            NumericArray(int new_size);
           ~NumericArray(); 
            NumericArray<Type>& operator=(const NumericArray<Type>& ar); 
            NumericArray<Type>& operator *(double factor) const;    
    };
    
    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) : Array<Type>( new_size)//: m_size(new_size), m_data(new Type[new_size])
    { 
    }
     
    template <class Type>
    NumericArray<Type>& NumericArray<Type>::operator=(const NumericArray<Type>& ar) 
    {
         Array<Type>::operator = (ar);  // call base class assignment operator
         return *this;
    }
    
    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(Array<Type>::Size());
       for(int i=0; i<Array::Size(); i++)
       {
          output[i] = (*this)[i] * factor;
          //return output;
       }
       return output;
    }
    #endif //NumericArray_h 
    
    
    //*******************
    //*******************
    //*******************
    //*******************
    1>------ Build started: Project: HP3_4.2b_ex2_with_inheritance, Configuration: Release Win32 ------
    1> main.cpp
    1>c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(60): warning C4172: returning address of local variable or temporary
    1> c:\all my\с++\ha level 6\solution\level 6\hp3_4.2b_ex2_with_inheritance\NumericArray.h(53) : while compiling class template member function 'NumericArray<Type> &NumericArray<Type>:perator *(double) const'
    1> with
    1> [
    1> Type=Point
    1> ]
    1> main.cpp(14) : see reference to class template instantiation 'NumericArray<Type>' being compiled
    1> with
    1> [
    1> Type=Point
    1> ]
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

    How crucial this warnings ?

  15. #30
    Join Date
    Apr 1999
    Posts
    26,799

    Re: generic inheritance

    Quote Originally Posted by oteel View Post
    I don't understand question sorry... and I don't understand what difference between your and my implementation assignment operator... more compact and more logic because call base class assignment ???
    The idea is this

    You are to assume that you have no idea how the parent class makes copies.. This means that the only choice you have is to call the parent class assignment operator.

    What if the parent class assignment operator changes? Are you going to fix your code trying to make those same changes in NumericArray? Why do that? Just call the parent assignment operator and let it do its work, whatever that work is.

    When you make a copy, you're supposed to make sure that the parent make its copy too. Your code did not do that, instead you just copied and pasted what the parent class did. What if the assignment in the parent was a 1,000 line function? Are you going to copy and paste 1,000 lines of code in your NumericArray assignment operator?

    You make the exact same mistake with your destructor -- why are you doing the work that the Array base class will do? Just let the Array class destructor do its job -- there is no need for you to duplicate code.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 20th, 2012 at 05:25 AM.

Page 2 of 3 FirstFirst 123 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